Merge branch 'master' of https://github.com/clicon/clixon
This commit is contained in:
commit
1d17c762d2
16 changed files with 142 additions and 200 deletions
43
CHANGELOG.md
43
CHANGELOG.md
|
|
@ -35,21 +35,27 @@ Expected: May 2020
|
||||||
* ca_trans_commit_done: Called when all plugin commits have been done.
|
* ca_trans_commit_done: Called when all plugin commits have been done.
|
||||||
* Note: If you have used "end" callback and usign transaction data, you should probably use this instead.
|
* Note: If you have used "end" callback and usign transaction data, you should probably use this instead.
|
||||||
|
|
||||||
### API changes on existing protocol/config features (You may have have to change how you use Clixon)
|
### API changes on existing protocol/config features (For users, you may have have to change how you use Clixon)
|
||||||
|
|
||||||
* Stricter validation detecting duplicate container or leaf in XML.
|
* Stricter validation detecting duplicate container or leaf in XML.
|
||||||
* Eg `<x><a/><a/></x>` is invalid if `a` is anything else than leaf or leaf-list
|
* Eg `<x><a/><a/></x>` is invalid if `a` is a leaf or container.
|
||||||
* New clixon-lib@2020-04-23.yang revision
|
* New clixon-lib@2020-04-23.yang revision
|
||||||
* Added: stats RPC for clixon XML and memory statistics.
|
* New RPC: `stats` for clixon XML and memory statistics.
|
||||||
* Added: restart-plugin RPC for restarting individual plugins without restarting backend.
|
* New RPC: `restart-plugin` for restarting individual plugins without restarting backend.
|
||||||
* xml-stats moved from clixon-config.yang as state data to an rpc `datastats` in clixon-lib.yang
|
* New clixon-config@2020-04-23.yang revision
|
||||||
|
* Removed xml-stats non-config data (replaced by rpc `stats` in clixon-lib.yang)
|
||||||
|
* Added option `CLICON_YANG_UNKNOWN_ANYDATA` to treat unknown XML (wrt YANG) as anydata.
|
||||||
|
* This is a way to loosen sanity checks if you need to accept eg unsynchronized YANG and XML
|
||||||
* Stricter incoming RPC sanity checking, error messages may have changed.
|
* Stricter incoming RPC sanity checking, error messages may have changed.
|
||||||
* Changed output of `clixon_cli -G` option to show generated CLI spec original text instead of resulting parse-tree, which gives better detail from a debugging perspective.
|
* Changed output of `clixon_cli -G` option to show generated CLI spec original text instead of resulting parse-tree, which gives better detail from a debugging perspective.
|
||||||
|
|
||||||
### C-API changes on existing features (you may need to change your plugin C-code)
|
### C-API changes on existing features (For developers: you may need to change your plugin C-code)
|
||||||
|
|
||||||
* Length of xml vector in many structs changed from `size_t` to `int`since it is a vector size, not byte size. This includes `transaction_data_t`
|
* Length of xml vector in many structs changed from `size_t` to `int`since it is a vector size, not byte size.
|
||||||
|
* Example: `transaction_data_t`
|
||||||
* `xml_merge()` changed to use 3-value return: 1:OK, 0:Yang failed, -1: Error
|
* `xml_merge()` changed to use 3-value return: 1:OK, 0:Yang failed, -1: Error
|
||||||
|
* Some function changed to use 3-value return: 1:OK, 0:Yang failed, -1: Error.
|
||||||
|
* Example: `xml_merge()`
|
||||||
* `clixon_netconf_error(category, xerr, msg, arg)` removed first argument -> `clixon_netconf_error(xerr, msg, arg)`
|
* `clixon_netconf_error(category, xerr, msg, arg)` removed first argument -> `clixon_netconf_error(xerr, msg, arg)`
|
||||||
* CLI
|
* CLI
|
||||||
* `clicon_parse()`: Changed signature due to new cligen error and result handling:
|
* `clicon_parse()`: Changed signature due to new cligen error and result handling:
|
||||||
|
|
@ -59,22 +65,23 @@ Expected: May 2020
|
||||||
|
|
||||||
* Added decriptive error message when plugins produce invalid state XML.
|
* Added decriptive error message when plugins produce invalid state XML.
|
||||||
* Example: `<error-tag>operation-failed</error-tag><error-info><bad-element>mystate</bad-element></error-info><error-message>No such yang module. Internal error, state callback returned invalid XML: example_backend</error-message>`
|
* Example: `<error-tag>operation-failed</error-tag><error-info><bad-element>mystate</bad-element></error-info><error-message>No such yang module. Internal error, state callback returned invalid XML: example_backend</error-message>`
|
||||||
* Added option `CLICON_YANG_UNKNOWN_ANYDATA` to treat unknown XML (wrt YANG) as anydata.
|
* Such a message means there is something wrong in the internal plugins or elsewehere, ie it is not a proper end-user error.
|
||||||
* This is a way to loosen sanity checks if you need to accept eg unsynchronized YANG and XML
|
|
||||||
* Compile-time option: `USE_CLIGEN44` for running clixon-45 with cligen-44.
|
* Compile-time option: `USE_CLIGEN44` for running clixon-45 with cligen-44.
|
||||||
* Temporary fix since cligen-45 have some non-backward compatible behaviour.
|
* Temporary fix since cligen-45 have some non-backward compatible behaviour.
|
||||||
* Optimizations
|
* Cycle optimizations
|
||||||
* Reduced memory for attribute and body objects, see `XML_NEW_DIFFERENTIATE` compile-time option.
|
* Optimized namespace prefix checks at xml parse time: using many prefixes slowed down parsing considerably
|
||||||
* Optimized prefix checks at xml parse time: using many prefixes slowed down parsing considerably
|
* Optimized cbuf handling in parsing and xml2cbuf functions: use of new `cbuf_append()` function.
|
||||||
* Optimized cbuf handling in parsing and xml2cbuf functions.
|
|
||||||
* Optimized xml scanner to read strings rather than single chars
|
* Optimized xml scanner to read strings rather than single chars
|
||||||
* Optimized xml_merge for the case of disjunct trees.
|
* Identify early that trees are disjunct instead of recursively merge in `xml_merge`
|
||||||
* Cleared startup-db cache after restart
|
* Optimizations of `yang_bind` for large lists: use a "sibling/template" to use same binding as previous element.
|
||||||
* Experimental optimzations of yang-bind and sort for large lists
|
* Memory optimizations
|
||||||
* Enabled by compile-time options: `OPTIMIZE_45_BIND` and `OPTIMIZE_45_SORT`
|
* Reduced memory for attribute and body objects, by allocating less memory in `xml_new()` than for elements, reducing XML storage with ca 25%
|
||||||
|
* Cleared startup-db cache after restart, slashing datastore cache with (best-case) a third.
|
||||||
|
* Removed nameserver binding cache for leaf/leaf-list objects.
|
||||||
|
* Remove xml value cache after sorting (just use cligen value cache at sorting, remove after use)
|
||||||
* Adapted to CLIgen 4.5 API changes, eg: `cliread()` and `cliread_parse()`
|
* Adapted to CLIgen 4.5 API changes, eg: `cliread()` and `cliread_parse()`
|
||||||
* Renamed utility function `clixon_util_insert()` to `clixon_util_xml_mod()` and added merge functionality.
|
* Renamed utility function `clixon_util_insert()` to `clixon_util_xml_mod()` and added merge functionality.
|
||||||
* Sanity check of duplicates prefixes in Yang modules and submodules as defined in RFC 7950 Sec 7.1.4
|
* Sanity check of duplicate prefixes in Yang modules and submodules as defined in RFC 7950 Sec 7.1.4
|
||||||
|
|
||||||
### Corrected Bugs
|
### Corrected Bugs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1425,7 +1425,6 @@ from_client_stats(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RESTART_PLUGIN_RPC
|
|
||||||
/*! Request restart of specific plugins
|
/*! Request restart of specific plugins
|
||||||
* @param[in] h Clicon handle
|
* @param[in] h Clicon handle
|
||||||
* @param[in] xe Request: <rpc><xn></rpc>
|
* @param[in] xe Request: <rpc><xn></rpc>
|
||||||
|
|
@ -1472,7 +1471,6 @@ from_client_restart_plugin(clicon_handle h,
|
||||||
free(vec);
|
free(vec);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
#endif /* RESTART_PLUGIN_RPC */
|
|
||||||
|
|
||||||
/*! Verify nacm user with peer uid credentials
|
/*! Verify nacm user with peer uid credentials
|
||||||
* @param[in] mode Peer credential mode: none, exact or except
|
* @param[in] mode Peer credential mode: none, exact or except
|
||||||
|
|
@ -1838,11 +1836,9 @@ backend_rpc_init(clicon_handle h)
|
||||||
if (rpc_callback_register(h, from_client_stats, NULL,
|
if (rpc_callback_register(h, from_client_stats, NULL,
|
||||||
CLIXON_LIB_NS, "stats") < 0)
|
CLIXON_LIB_NS, "stats") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
#ifdef RESTART_PLUGIN_RPC
|
|
||||||
if (rpc_callback_register(h, from_client_restart_plugin, NULL,
|
if (rpc_callback_register(h, from_client_restart_plugin, NULL,
|
||||||
CLIXON_LIB_NS, "restart-plugin") < 0)
|
CLIXON_LIB_NS, "restart-plugin") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
#endif
|
|
||||||
retval =0;
|
retval =0;
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
||||||
|
|
@ -810,7 +810,6 @@ from_client_validate(clicon_handle h,
|
||||||
return retval;
|
return retval;
|
||||||
} /* from_client_validate */
|
} /* from_client_validate */
|
||||||
|
|
||||||
#ifdef RESTART_PLUGIN_RPC
|
|
||||||
/*! Restart specific backend plugins without full backend restart
|
/*! Restart specific backend plugins without full backend restart
|
||||||
* Note, depending on plugin callbacks, there may be other dependencies which may make this
|
* Note, depending on plugin callbacks, there may be other dependencies which may make this
|
||||||
* difficult in the general case.
|
* difficult in the general case.
|
||||||
|
|
@ -928,4 +927,4 @@ from_client_restart_one(clicon_handle h,
|
||||||
retval = 0;
|
retval = 0;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
#endif /* RESTART_PLUGIN_RPC */
|
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,6 @@ int from_client_commit(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void
|
||||||
int from_client_discard_changes(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void *regarg);
|
int from_client_discard_changes(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void *regarg);
|
||||||
int from_client_cancel_commit(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void *regarg);
|
int from_client_cancel_commit(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void *regarg);
|
||||||
int from_client_validate(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void *regarg);
|
int from_client_validate(clicon_handle h, cxobj *xe, cbuf *cbret, void *arg, void *regarg);
|
||||||
#ifdef RESTART_PLUGIN_RPC
|
|
||||||
int from_client_restart_one(clicon_handle h, clixon_plugin *cp, cbuf *cbret);
|
int from_client_restart_one(clicon_handle h, clixon_plugin *cp, cbuf *cbret);
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _BACKEND_COMMIT_H_ */
|
#endif /* _BACKEND_COMMIT_H_ */
|
||||||
|
|
|
||||||
|
|
@ -101,26 +101,6 @@
|
||||||
*/
|
*/
|
||||||
#define STATE_ORDERED_BY_SYSTEM
|
#define STATE_ORDERED_BY_SYSTEM
|
||||||
|
|
||||||
/*! Restart specific backend plugins
|
|
||||||
* Note, depending on plugin callbacks, there may be other dependencies which may make this
|
|
||||||
* difficult in the general case.
|
|
||||||
*/
|
|
||||||
#define RESTART_PLUGIN_RPC
|
|
||||||
|
|
||||||
/*! Differentiate creating XML object body/element vs elenmet to reduce space
|
|
||||||
*/
|
|
||||||
#define XML_NEW_DIFFERENTIATE
|
|
||||||
|
|
||||||
/*! Clixon 4.5 optimizing experiments for yang bind
|
|
||||||
* Primarily for large lists
|
|
||||||
*/
|
|
||||||
#define OPTIMIZE_45_BIND
|
|
||||||
|
|
||||||
/*! Clixon 4.5 optimizing experiments for sorting yang-bound XML trees
|
|
||||||
* Primarily for large lists
|
|
||||||
*/
|
|
||||||
#define OPTIMIZE_45_SORT
|
|
||||||
|
|
||||||
/*! Use cligen 4.4 instead of master / cligen 4.5.pre
|
/*! Use cligen 4.4 instead of master / cligen 4.5.pre
|
||||||
* Temporary fix
|
* Temporary fix
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
/*
|
/*
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
int xml_bind_yang_unknown_anydata(int bool);
|
int xml_bind_yang_unknown_anydata(int val);
|
||||||
int xml_bind_yang_rpc(cxobj *xrpc, yang_stmt *yspec, cxobj **xerr);
|
int xml_bind_yang_rpc(cxobj *xrpc, yang_stmt *yspec, cxobj **xerr);
|
||||||
int xml_bind_yang_rpc_reply(cxobj *xrpc, char *name, yang_stmt *yspec, cxobj **xerr);
|
int xml_bind_yang_rpc_reply(cxobj *xrpc, char *name, yang_stmt *yspec, cxobj **xerr);
|
||||||
int xml_bind_yang0(cxobj *xt, yang_bind yb, yang_stmt *yspec, cxobj **xerr);
|
int xml_bind_yang0(cxobj *xt, yang_bind yb, yang_stmt *yspec, cxobj **xerr);
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ clicon_err_reset(void)
|
||||||
* @param[in] fn Inline function name (when called from clicon_err() macro)
|
* @param[in] fn Inline function name (when called from clicon_err() macro)
|
||||||
* @param[in] line Inline file line number (when called from clicon_err() macro)
|
* @param[in] line Inline file line number (when called from clicon_err() macro)
|
||||||
* @param[in] category Clixon error category, See enum clicon_err
|
* @param[in] category Clixon error category, See enum clicon_err
|
||||||
* @param[in] errno Error number, typically errno
|
* @param[in] suberr Error number, typically errno
|
||||||
* @param[in] reason Error string, format with argv
|
* @param[in] reason Error string, format with argv
|
||||||
* @see clicon_err_reser Resetting the global error variables.
|
* @see clicon_err_reser Resetting the global error variables.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,7 @@ struct search_index{
|
||||||
* - Local name: In either case the "local name" is N (also "prefix")
|
* - Local name: In either case the "local name" is N (also "prefix")
|
||||||
* It is this combination of the universally managed URI namespace with the
|
* It is this combination of the universally managed URI namespace with the
|
||||||
* vocabulary's local names that is effective in avoiding name clashes.
|
* vocabulary's local names that is effective in avoiding name clashes.
|
||||||
|
* @see struct xmlbody For XML body and attributes
|
||||||
*/
|
*/
|
||||||
struct xml{
|
struct xml{
|
||||||
enum cxobj_type x_type; /* type of node: element, attribute, body */
|
enum cxobj_type x_type; /* type of node: element, attribute, body */
|
||||||
|
|
@ -186,9 +187,8 @@ struct xml{
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Variant of struct xml for use by non-elements to save space
|
||||||
#ifdef XML_NEW_DIFFERENTIATE
|
* @see struct xml For XML elements
|
||||||
/* This is experimental variant of struct xml for use by non-elements to save space
|
|
||||||
*/
|
*/
|
||||||
struct xmlbody{
|
struct xmlbody{
|
||||||
enum cxobj_type xb_type; /* type of node: element, attribute, body */
|
enum cxobj_type xb_type; /* type of node: element, attribute, body */
|
||||||
|
|
@ -201,7 +201,6 @@ struct xmlbody{
|
||||||
see xml_enumerate and xml_cmp */
|
see xml_enumerate and xml_cmp */
|
||||||
cbuf *xb_value_cb; /* attribute and body nodes have values */
|
cbuf *xb_value_cb; /* attribute and body nodes have values */
|
||||||
};
|
};
|
||||||
#endif /* XML_NEW_DIFFERENTIATE */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Variables
|
* Variables
|
||||||
|
|
@ -277,11 +276,7 @@ xml_stats_one(cxobj *x,
|
||||||
break;
|
break;
|
||||||
case CX_BODY:
|
case CX_BODY:
|
||||||
case CX_ATTR:
|
case CX_ATTR:
|
||||||
#ifdef XML_NEW_DIFFERENTIATE
|
|
||||||
sz += sizeof(struct xmlbody);
|
sz += sizeof(struct xmlbody);
|
||||||
#else
|
|
||||||
sz += sizeof(struct xml);
|
|
||||||
#endif
|
|
||||||
if (x->x_value_cb)
|
if (x->x_value_cb)
|
||||||
sz += cbuf_buflen(x->x_value_cb);
|
sz += cbuf_buflen(x->x_value_cb);
|
||||||
break;
|
break;
|
||||||
|
|
@ -1042,10 +1037,9 @@ xml_childvec_get(cxobj *x)
|
||||||
* ...
|
* ...
|
||||||
* xml_free(x);
|
* xml_free(x);
|
||||||
* @endcode
|
* @endcode
|
||||||
|
* @note Differentiates between body/attribute vs element to reduce mem allocation
|
||||||
* @see xml_sort_insert
|
* @see xml_sort_insert
|
||||||
*/
|
*/
|
||||||
#ifdef XML_NEW_DIFFERENTIATE
|
|
||||||
/* Differentiate creating XML object body/element vs elenmet to reduce space */
|
|
||||||
cxobj *
|
cxobj *
|
||||||
xml_new(char *name,
|
xml_new(char *name,
|
||||||
cxobj *xp,
|
cxobj *xp,
|
||||||
|
|
@ -1085,35 +1079,6 @@ xml_new(char *name,
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* XML_NEW_DIFFERENTIATE */
|
|
||||||
|
|
||||||
cxobj *
|
|
||||||
xml_new(char *name,
|
|
||||||
cxobj *xp,
|
|
||||||
enum cxobj_type type)
|
|
||||||
{
|
|
||||||
cxobj *x;
|
|
||||||
|
|
||||||
if ((x = malloc(sizeof(cxobj))) == NULL){
|
|
||||||
clicon_err(OE_XML, errno, "malloc");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
memset(x, 0, sizeof(cxobj));
|
|
||||||
xml_type_set(x, type);
|
|
||||||
if (name != NULL &&
|
|
||||||
xml_name_set(x, name) < 0)
|
|
||||||
return NULL;
|
|
||||||
if (xp){
|
|
||||||
xml_parent_set(x, xp);
|
|
||||||
if (xml_child_append(xp, x) < 0)
|
|
||||||
return NULL;
|
|
||||||
x->_x_i = xml_child_nr(xp)-1;
|
|
||||||
}
|
|
||||||
_stats_nr++;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
#endif /* XML_NEW_DIFFERENTIATE */
|
|
||||||
|
|
||||||
/*! Create a new XML node and set it's body to a value
|
/*! Create a new XML node and set it's body to a value
|
||||||
*
|
*
|
||||||
* @param[in] name The name of the new node
|
* @param[in] name The name of the new node
|
||||||
|
|
|
||||||
|
|
@ -88,9 +88,9 @@ static int _yang_unknown_anydata = 0;
|
||||||
* The problem with this is that its global and shuld be bound to a handle
|
* The problem with this is that its global and shuld be bound to a handle
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xml_bind_yang_unknown_anydata(int bool)
|
xml_bind_yang_unknown_anydata(int val)
|
||||||
{
|
{
|
||||||
_yang_unknown_anydata = bool;
|
_yang_unknown_anydata = val;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,9 +128,7 @@ strip_whitespace(cxobj *xt)
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
populate_self_parent(cxobj *xt,
|
populate_self_parent(cxobj *xt,
|
||||||
#ifdef OPTIMIZE_45_BIND
|
|
||||||
cxobj *xsibling,
|
cxobj *xsibling,
|
||||||
#endif
|
|
||||||
cxobj **xerr)
|
cxobj **xerr)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
@ -143,14 +141,12 @@ populate_self_parent(cxobj *xt,
|
||||||
cbuf *cb = NULL;
|
cbuf *cb = NULL;
|
||||||
|
|
||||||
name = xml_name(xt);
|
name = xml_name(xt);
|
||||||
#ifdef OPTIMIZE_45_BIND
|
|
||||||
/* optimization for massive lists - use the first element as role model */
|
/* optimization for massive lists - use the first element as role model */
|
||||||
if (xsibling &&
|
if (xsibling &&
|
||||||
xml_child_nr_type(xt, CX_ATTR) == 0){
|
xml_child_nr_type(xt, CX_ATTR) == 0){
|
||||||
y = xml_spec(xsibling);
|
y = xml_spec(xsibling);
|
||||||
goto set;
|
goto set;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
xp = xml_parent(xt);
|
xp = xml_parent(xt);
|
||||||
if (xp == NULL){
|
if (xp == NULL){
|
||||||
if (xerr &&
|
if (xerr &&
|
||||||
|
|
@ -202,9 +198,7 @@ populate_self_parent(cxobj *xt,
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
#ifdef OPTIMIZE_45_BIND
|
|
||||||
set:
|
set:
|
||||||
#endif
|
|
||||||
xml_spec_set(xt, y);
|
xml_spec_set(xt, y);
|
||||||
#ifdef XML_EXPLICIT_INDEX
|
#ifdef XML_EXPLICIT_INDEX
|
||||||
if (xml_search_index_p(xt))
|
if (xml_search_index_p(xt))
|
||||||
|
|
@ -354,7 +348,6 @@ xml_bind_yang(cxobj *xt,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OPTIMIZE_45_BIND
|
|
||||||
int
|
int
|
||||||
xml_bind_yang0_opt(cxobj *xt,
|
xml_bind_yang0_opt(cxobj *xt,
|
||||||
yang_bind yb,
|
yang_bind yb,
|
||||||
|
|
@ -424,8 +417,6 @@ xml_bind_yang0_opt(cxobj *xt,
|
||||||
retval = 0;
|
retval = 0;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
#endif /* OPTIMIZE_45_BIND */
|
|
||||||
|
|
||||||
|
|
||||||
/*! Find yang spec association of tree of XML nodes
|
/*! Find yang spec association of tree of XML nodes
|
||||||
*
|
*
|
||||||
|
|
@ -455,11 +446,7 @@ xml_bind_yang0(cxobj *xt,
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case YB_PARENT:
|
case YB_PARENT:
|
||||||
if ((ret = populate_self_parent(xt,
|
if ((ret = populate_self_parent(xt, NULL, xerr)) < 0)
|
||||||
#ifdef OPTIMIZE_45_BIND
|
|
||||||
NULL,
|
|
||||||
#endif
|
|
||||||
xerr)) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case YB_NONE:
|
case YB_NONE:
|
||||||
|
|
@ -477,13 +464,8 @@ xml_bind_yang0(cxobj *xt,
|
||||||
strip_whitespace(xt);
|
strip_whitespace(xt);
|
||||||
xc = NULL; /* Apply on children */
|
xc = NULL; /* Apply on children */
|
||||||
while ((xc = xml_child_each(xt, xc, CX_ELMNT)) != NULL) {
|
while ((xc = xml_child_each(xt, xc, CX_ELMNT)) != NULL) {
|
||||||
#ifdef OPTIMIZE_45_BIND
|
|
||||||
if ((ret = xml_bind_yang0_opt(xc, YB_PARENT, NULL, xerr)) < 0)
|
if ((ret = xml_bind_yang0_opt(xc, YB_PARENT, NULL, xerr)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
#else
|
|
||||||
if ((ret = xml_bind_yang0(xc, YB_PARENT, NULL, xerr)) < 0)
|
|
||||||
goto done;
|
|
||||||
#endif
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
failed++;
|
failed++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -464,9 +464,7 @@ xml2ns(cxobj *x,
|
||||||
* If not, this is devastating when populating deep yang structures
|
* If not, this is devastating when populating deep yang structures
|
||||||
*/
|
*/
|
||||||
if (ns &&
|
if (ns &&
|
||||||
#ifdef OPTIMIZE_45_BIND /* Dont set cache if few children: if 1 child typically a body */
|
xml_child_nr(x) > 1 && /* Dont set cache if few children: if 1 child typically a body */
|
||||||
xml_child_nr(x) > 1 &&
|
|
||||||
#endif
|
|
||||||
nscache_set(x, prefix, ns) < 0)
|
nscache_set(x, prefix, ns) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
ok:
|
ok:
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,6 @@ xml_cv_cache(cxobj *x,
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OPTIMIZE_45_SORT
|
|
||||||
static int
|
static int
|
||||||
xml_cv_cache_clear(cxobj *xt)
|
xml_cv_cache_clear(cxobj *xt)
|
||||||
{
|
{
|
||||||
|
|
@ -157,7 +156,6 @@ xml_cv_cache_clear(cxobj *xt)
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
#endif /* OPTIMIZE_45_SORT */
|
|
||||||
|
|
||||||
/*! Help function to qsort for sorting entries in xml child vector same parent
|
/*! Help function to qsort for sorting entries in xml child vector same parent
|
||||||
* @param[in] x1 object 1
|
* @param[in] x1 object 1
|
||||||
|
|
@ -433,7 +431,6 @@ xml_sort_recurse(cxobj *xn)
|
||||||
cxobj *x;
|
cxobj *x;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
#ifdef OPTIMIZE_45_SORT
|
|
||||||
ret = xml_sort_verify(xn, NULL);
|
ret = xml_sort_verify(xn, NULL);
|
||||||
if (ret == 1) /* This node is not sortable */
|
if (ret == 1) /* This node is not sortable */
|
||||||
goto ok;
|
goto ok;
|
||||||
|
|
@ -445,12 +442,6 @@ xml_sort_recurse(cxobj *xn)
|
||||||
}
|
}
|
||||||
if (xml_cv_cache_clear(xn) < 0)
|
if (xml_cv_cache_clear(xn) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
#else
|
|
||||||
if ((ret = xml_sort(xn)) < 0)
|
|
||||||
goto done;
|
|
||||||
if (ret == 1) /* This node is not sortable */
|
|
||||||
goto ok;
|
|
||||||
#endif
|
|
||||||
x = NULL;
|
x = NULL;
|
||||||
while ((x = xml_child_each(xn, x, CX_ELMNT)) != NULL) {
|
while ((x = xml_child_each(xn, x, CX_ELMNT)) != NULL) {
|
||||||
if (xml_sort_recurse(x) < 0)
|
if (xml_sort_recurse(x) < 0)
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ expectfn "$clixon_cli -1 -f $cfg set interfaces interface eth/0/0 ipv4 address 1
|
||||||
|
|
||||||
new "cli configure ip descr"
|
new "cli configure ip descr"
|
||||||
expectfn "$clixon_cli -1 -f $cfg set interfaces interface eth/0/0 description mydesc" 0 "^$"
|
expectfn "$clixon_cli -1 -f $cfg set interfaces interface eth/0/0 description mydesc" 0 "^$"
|
||||||
|
|
||||||
new "cli configure ip type"
|
new "cli configure ip type"
|
||||||
expectfn "$clixon_cli -1 -f $cfg set interfaces interface eth/0/0 type ex:eth" 0 "^$"
|
expectfn "$clixon_cli -1 -f $cfg set interfaces interface eth/0/0 type ex:eth" 0 "^$"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
#
|
#
|
||||||
# Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
|
# Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren
|
||||||
# Copyright (C) 2017-2019 Olof Hagsand
|
# Copyright (C) 2017-2019 Olof Hagsand
|
||||||
# Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate)#
|
# Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate)
|
||||||
# This file is part of CLIXON
|
# This file is part of CLIXON
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
@ -42,7 +42,7 @@ datarootdir = @datarootdir@
|
||||||
# See also OPT_YANG_INSTALLDIR for the standard yang files
|
# See also OPT_YANG_INSTALLDIR for the standard yang files
|
||||||
YANG_INSTALLDIR = @YANG_INSTALLDIR@
|
YANG_INSTALLDIR = @YANG_INSTALLDIR@
|
||||||
|
|
||||||
YANGSPECS = clixon-config@2020-02-22.yang
|
YANGSPECS = clixon-config@2020-04-23.yang
|
||||||
YANGSPECS += clixon-lib@2020-04-23.yang
|
YANGSPECS += clixon-lib@2020-04-23.yang
|
||||||
YANGSPECS += clixon-rfc5277@2008-07-01.yang
|
YANGSPECS += clixon-rfc5277@2008-07-01.yang
|
||||||
YANGSPECS += clixon-xml-changelog@2019-03-21.yang
|
YANGSPECS += clixon-xml-changelog@2019-03-21.yang
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,6 @@ module clixon-config {
|
||||||
|
|
||||||
***** END LICENSE BLOCK *****";
|
***** END LICENSE BLOCK *****";
|
||||||
|
|
||||||
/* Deleted: clixon-stats state for clixon XML and memory statistics. (moved to clixon-lib)
|
|
||||||
*/
|
|
||||||
revision 2020-02-22 {
|
revision 2020-02-22 {
|
||||||
description
|
description
|
||||||
"Added: search index extension,
|
"Added: search index extension,
|
||||||
|
|
@ -314,14 +312,6 @@ module clixon-config {
|
||||||
Some yang specs seem not to fulfil this. However, if you reset this, there may
|
Some yang specs seem not to fulfil this. However, if you reset this, there may
|
||||||
be follow-up errors due to code that assumes a configuration list has keys";
|
be follow-up errors due to code that assumes a configuration list has keys";
|
||||||
}
|
}
|
||||||
leaf CLICON_YANG_UNKNOWN_ANYDATA{
|
|
||||||
type boolean;
|
|
||||||
default false;
|
|
||||||
description
|
|
||||||
"Treat unknown XML/JSON nodes as anydata.
|
|
||||||
This does not apply to namespaces, which means a top-level node: xxx:yyy
|
|
||||||
is accepted only if yyy is unknown, not xxx";
|
|
||||||
}
|
|
||||||
leaf CLICON_BACKEND_DIR {
|
leaf CLICON_BACKEND_DIR {
|
||||||
type string;
|
type string;
|
||||||
description
|
description
|
||||||
|
|
@ -728,4 +718,33 @@ module clixon-config {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
container clixon-stats{
|
||||||
|
config false;
|
||||||
|
description "Clixon backend statistics.";
|
||||||
|
container global{
|
||||||
|
description "Clixon global statistics";
|
||||||
|
leaf xmlnr{
|
||||||
|
description "Number of XML objects. That is number of residing xml/json objects
|
||||||
|
in the internal 'cxobj' representation.";
|
||||||
|
type uint64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list datastore{
|
||||||
|
description "Datastore statistics";
|
||||||
|
key "name";
|
||||||
|
leaf name{
|
||||||
|
description "name of datastore (eg running).";
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
leaf nr{
|
||||||
|
description "Number of XML objects. That is number of residing xml/json objects
|
||||||
|
in the internal 'cxobj' representation.";
|
||||||
|
type uint64;
|
||||||
|
}
|
||||||
|
leaf size{
|
||||||
|
description "Size in bytes of internal datastore cache of datastore tree.";
|
||||||
|
type uint64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ module clixon-config {
|
||||||
"Clixon configuration file
|
"Clixon configuration file
|
||||||
***** BEGIN LICENSE BLOCK *****
|
***** BEGIN LICENSE BLOCK *****
|
||||||
Copyright (C) 2009-2019 Olof Hagsand
|
Copyright (C) 2009-2019 Olof Hagsand
|
||||||
|
Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate)
|
||||||
|
|
||||||
This file is part of CLIXON
|
This file is part of CLIXON
|
||||||
|
|
||||||
|
|
@ -39,6 +40,22 @@ module clixon-config {
|
||||||
|
|
||||||
***** END LICENSE BLOCK *****";
|
***** END LICENSE BLOCK *****";
|
||||||
|
|
||||||
|
/* Deleted: clixon-stats state for clixon XML and memory statistics. (moved to clixon-lib)
|
||||||
|
*/
|
||||||
|
revision 2020-04-23 {
|
||||||
|
description
|
||||||
|
"Added: CLICON_YANG_UNKNOWN_ANYDATA to treat unknown XML (wrt YANG) as anydata.
|
||||||
|
Deleted: xml-stats non-config data (replaced by rpc stats in clixon-lib.yang)";
|
||||||
|
}
|
||||||
|
revision 2020-02-22 {
|
||||||
|
description
|
||||||
|
"Added: search index extension,
|
||||||
|
Added: clixon-stats state for clixon XML and memory statistics.
|
||||||
|
Added: CLICON_CLI_BUF_START and CLICON_CLI_BUF_THRESHOLD for quadratic and linear
|
||||||
|
growth of CLIgen buffers (cbuf:s)
|
||||||
|
Added: CLICON_VALIDATE_STATE_XML for controling validation of user state XML
|
||||||
|
Added: CLICON_CLICON_YANG_LIST_CHECK to skip list key checks";
|
||||||
|
}
|
||||||
revision 2019-09-11 {
|
revision 2019-09-11 {
|
||||||
description
|
description
|
||||||
"Added: CLICON_BACKEND_USER: drop of privileges to user,
|
"Added: CLICON_BACKEND_USER: drop of privileges to user,
|
||||||
|
|
@ -67,6 +84,10 @@ module clixon-config {
|
||||||
description
|
description
|
||||||
"Released in Clixon 3.8";
|
"Released in Clixon 3.8";
|
||||||
}
|
}
|
||||||
|
extension search_index {
|
||||||
|
description "This list argument acts as a search index using optimized binary search.
|
||||||
|
";
|
||||||
|
}
|
||||||
typedef startup_mode{
|
typedef startup_mode{
|
||||||
description
|
description
|
||||||
"Which method to boot/start clicon backend.
|
"Which method to boot/start clicon backend.
|
||||||
|
|
@ -289,6 +310,23 @@ module clixon-config {
|
||||||
There is a 'good-enough' posix translation mode and a complete
|
There is a 'good-enough' posix translation mode and a complete
|
||||||
libxml2 mode";
|
libxml2 mode";
|
||||||
}
|
}
|
||||||
|
leaf CLICON_YANG_LIST_CHECK {
|
||||||
|
type boolean;
|
||||||
|
default true;
|
||||||
|
description
|
||||||
|
"If false, skip Yang list check sanity checks from RFC 7950, Sec 7.8.2:
|
||||||
|
The 'key' statement, which MUST be present if the list represents configuration.
|
||||||
|
Some yang specs seem not to fulfil this. However, if you reset this, there may
|
||||||
|
be follow-up errors due to code that assumes a configuration list has keys";
|
||||||
|
}
|
||||||
|
leaf CLICON_YANG_UNKNOWN_ANYDATA{
|
||||||
|
type boolean;
|
||||||
|
default false;
|
||||||
|
description
|
||||||
|
"Treat unknown XML/JSON nodes as anydata.
|
||||||
|
This does not apply to namespaces, which means a top-level node: xxx:yyy
|
||||||
|
is accepted only if yyy is unknown, not xxx";
|
||||||
|
}
|
||||||
leaf CLICON_BACKEND_DIR {
|
leaf CLICON_BACKEND_DIR {
|
||||||
type string;
|
type string;
|
||||||
description
|
description
|
||||||
|
|
@ -440,6 +478,25 @@ module clixon-config {
|
||||||
Also, if CLICON_CLI_HIST_FILE is set, also the size in lines
|
Also, if CLICON_CLI_HIST_FILE is set, also the size in lines
|
||||||
of the saved history.";
|
of the saved history.";
|
||||||
}
|
}
|
||||||
|
leaf CLICON_CLI_BUF_START {
|
||||||
|
type uint32;
|
||||||
|
default 256;
|
||||||
|
description
|
||||||
|
"CLIgen buffer (cbuf) initial size.
|
||||||
|
When the buffer needs to grow, the allocation grows quadratic up to a threshold
|
||||||
|
after which linear growth continues.
|
||||||
|
See CLICON_CLI_BUF_THRESHOLD";
|
||||||
|
}
|
||||||
|
leaf CLICON_CLI_BUF_THRESHOLD {
|
||||||
|
type uint32;
|
||||||
|
default 65536;
|
||||||
|
description
|
||||||
|
"CLIgen buffer (cbuf) threshold size.
|
||||||
|
When the buffer exceeds the threshold, the allocation grows by adding the threshold
|
||||||
|
value to the buffer length.
|
||||||
|
If 0, the growth continues with quadratic growth.
|
||||||
|
See CLICON_CLI_BUF_THRESHOLD";
|
||||||
|
}
|
||||||
leaf CLICON_SOCK_FAMILY {
|
leaf CLICON_SOCK_FAMILY {
|
||||||
type string;
|
type string;
|
||||||
default "UNIX";
|
default "UNIX";
|
||||||
|
|
@ -552,6 +609,20 @@ module clixon-config {
|
||||||
If CLICON_XML_CHANGELOG is true, Clixon
|
If CLICON_XML_CHANGELOG is true, Clixon
|
||||||
reads the module changelog from this file.";
|
reads the module changelog from this file.";
|
||||||
}
|
}
|
||||||
|
leaf CLICON_VALIDATE_STATE_XML {
|
||||||
|
type boolean;
|
||||||
|
default false;
|
||||||
|
description
|
||||||
|
"Validate user state callback content.
|
||||||
|
Users may register state callbacks using ca_statedata callback
|
||||||
|
When set, the XML returned from the callback is validated after merging with
|
||||||
|
the running db. If it fails, an internal error is returned to the originating
|
||||||
|
user.
|
||||||
|
If the option is not set, the XML returned by the user is not validated.
|
||||||
|
Note that enabling currently causes a large performance overhead for large
|
||||||
|
lists, therefore it is recommended to enable it during development and debugging
|
||||||
|
but disable it in production, until this has been resolved.";
|
||||||
|
}
|
||||||
leaf CLICON_STARTUP_MODE {
|
leaf CLICON_STARTUP_MODE {
|
||||||
type startup_mode;
|
type startup_mode;
|
||||||
description "Which method to boot/start clicon backend";
|
description "Which method to boot/start clicon backend";
|
||||||
|
|
@ -560,7 +631,9 @@ module clixon-config {
|
||||||
type boolean;
|
type boolean;
|
||||||
default false;
|
default false;
|
||||||
description "If set, modifications in validation and commit
|
description "If set, modifications in validation and commit
|
||||||
callbacks are written back into the datastore";
|
callbacks are written back into the datastore.
|
||||||
|
This is a bad idea and therefore obsoleted.";
|
||||||
|
status obsolete;
|
||||||
}
|
}
|
||||||
leaf CLICON_NACM_MODE {
|
leaf CLICON_NACM_MODE {
|
||||||
type nacm_mode;
|
type nacm_mode;
|
||||||
|
|
@ -659,6 +732,5 @@ module clixon-config {
|
||||||
data to store before dropping. 0 means no retention";
|
data to store before dropping. 0 means no retention";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
module clixon-lib {
|
|
||||||
yang-version 1.1;
|
|
||||||
namespace "http://clicon.org/lib";
|
|
||||||
prefix cl;
|
|
||||||
|
|
||||||
organization
|
|
||||||
"Clicon / Clixon";
|
|
||||||
|
|
||||||
contact
|
|
||||||
"Olof Hagsand <olof@hagsand.se>";
|
|
||||||
|
|
||||||
description
|
|
||||||
"Clixon Netconf extensions for communication between clients and backend.
|
|
||||||
|
|
||||||
***** BEGIN LICENSE BLOCK *****
|
|
||||||
Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren
|
|
||||||
|
|
||||||
This file is part of CLIXON
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the \"License\");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an \"AS IS\" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
Alternatively, the contents of this file may be used under the terms of
|
|
||||||
the GNU General Public License Version 3 or later (the \"GPL\"),
|
|
||||||
in which case the provisions of the GPL are applicable instead
|
|
||||||
of those above. If you wish to allow use of your version of this file only
|
|
||||||
under the terms of the GPL, and not to allow others to
|
|
||||||
use your version of this file under the terms of Apache License version 2,
|
|
||||||
indicate your decision by deleting the provisions above and replace them with
|
|
||||||
the notice and other provisions required by the GPL. If you do not delete
|
|
||||||
the provisions above, a recipient may use your version of this file under
|
|
||||||
the terms of any one of the Apache License version 2 or the GPL.
|
|
||||||
|
|
||||||
***** END LICENSE BLOCK *****";
|
|
||||||
|
|
||||||
revision 2019-08-13 {
|
|
||||||
description
|
|
||||||
"No changes (reverted change)";
|
|
||||||
}
|
|
||||||
revision 2019-06-05 {
|
|
||||||
description
|
|
||||||
"ping rpc added for liveness";
|
|
||||||
}
|
|
||||||
revision 2019-01-02 {
|
|
||||||
description
|
|
||||||
"Released in Clixon 3.9";
|
|
||||||
}
|
|
||||||
rpc debug {
|
|
||||||
description "Set debug level of backend.";
|
|
||||||
input {
|
|
||||||
leaf level {
|
|
||||||
type uint32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rpc ping {
|
|
||||||
description "Check aliveness of backend daemon.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue