Added new DOMAIN level in YANG spec structure

This commit is contained in:
Olof hagsand 2024-10-06 09:18:24 +02:00
parent 0c8aef0291
commit f0bd103e79
17 changed files with 201 additions and 68 deletions

View file

@ -102,6 +102,7 @@
*/
/*! Names of top-level data YANGs
*/
#define YANG_DOMAIN_TOP "top"
#define YANG_DATA_TOP "data" /* "dbspec" */
#define YANG_CONFIG_TOP "config"
#define YANG_NACM_TOP "nacm_ext_yang"
@ -190,8 +191,9 @@ enum rfc_6020{
Y_YANG_VERSION,
Y_YIN_ELEMENT,
/* Note, from here not actual yang statement from the RFC */
Y_MOUNTS, /* Top-level all mounts */
Y_SPEC /* Specifications on top, config or mount-points */
Y_MOUNTS, /* Top-level root single object, see clixon_yang_mounts_get() */
Y_DOMAIN, /* YANG domain: many module revisions allowed but name+revision unique */
Y_SPEC /* Module set for single data, config and mount-point: unique module name */
};
/* Type used to group yang nodes used in some functions
@ -286,7 +288,9 @@ int yang_stats(yang_stmt *y, enum rfc_6020 keyw, uint64_t *nrp, size_t *s
/* Other functions */
yang_stmt *yspec_new(clixon_handle h, char *name);
yang_stmt *yspec_new1(clixon_handle h, char *domain, char *name);
yang_stmt *yspec_new_shared(clixon_handle h, char *name, char *domain, yang_stmt *yspec0);
yang_stmt *ydomain_new(clixon_handle h, char *domain);
yang_stmt *ys_new(enum rfc_6020 keyw);
yang_stmt *ys_prune(yang_stmt *yp, int i);
int ys_prune_self(yang_stmt *ys);
@ -304,6 +308,7 @@ int ys_module_by_xml(yang_stmt *ysp, struct xml *xt, yang_stmt **ymodp);
yang_stmt *ys_module(yang_stmt *ys);
int ys_real_module(yang_stmt *ys, yang_stmt **ymod);
yang_stmt *ys_spec(yang_stmt *ys);
yang_stmt *ys_domain(yang_stmt *ys);
yang_stmt *ys_mounts(yang_stmt *ys);
yang_stmt *yang_find(yang_stmt *yn, int keyword, const char *argument);
yang_stmt *yang_find_datanode(yang_stmt *yn, char *argument);

View file

@ -354,11 +354,13 @@ clixon_yang_mounts_set(clixon_handle h,
yang_stmt *
clicon_dbspec_yang(clixon_handle h)
{
yang_stmt *ymounts;
yang_stmt *ydomain;
yang_stmt *ys = NULL;
yang_stmt *ymounts = NULL;
if ((ymounts = clixon_yang_mounts_get(h)) != NULL)
ys = yang_find(ymounts, Y_SPEC, YANG_DATA_TOP);
if ((ymounts = clixon_yang_mounts_get(h)) != NULL &&
(ydomain = yang_find(ymounts, Y_DOMAIN, YANG_DOMAIN_TOP)) != NULL)
ys = yang_find(ydomain, Y_SPEC, YANG_DATA_TOP);
return ys;
}
@ -371,11 +373,13 @@ clicon_dbspec_yang(clixon_handle h)
yang_stmt *
clicon_config_yang(clixon_handle h)
{
yang_stmt *ymounts = NULL;
yang_stmt *ymounts;
yang_stmt *ydomain;
yang_stmt *ys = NULL;
if ((ymounts = clixon_yang_mounts_get(h)) != NULL)
ys = yang_find(ymounts, Y_SPEC, YANG_CONFIG_TOP);
if ((ymounts = clixon_yang_mounts_get(h)) != NULL &&
(ydomain = yang_find(ymounts, Y_DOMAIN, YANG_DOMAIN_TOP)) != NULL)
ys = yang_find(ydomain, Y_SPEC, YANG_CONFIG_TOP);
return ys;
}
@ -388,11 +392,13 @@ clicon_config_yang(clixon_handle h)
yang_stmt *
clicon_nacm_ext_yang(clixon_handle h)
{
yang_stmt *ymounts = NULL;
yang_stmt *ymounts;
yang_stmt *ydomain;
yang_stmt *ys = NULL;
if ((ymounts = clixon_yang_mounts_get(h)) != NULL)
ys = yang_find(ymounts, Y_SPEC, YANG_NACM_TOP);
if ((ymounts = clixon_yang_mounts_get(h)) != NULL &&
(ydomain = yang_find(ymounts, Y_DOMAIN, YANG_DOMAIN_TOP)) != NULL)
ys = yang_find(ydomain, Y_SPEC, YANG_NACM_TOP);
return ys;
}

View file

@ -708,7 +708,7 @@ xmldb_readfile(clixon_handle h,
* Same ymodules are inserted into yspec1, ie pointers only
*/
if (needclone && xmodfile){
if ((yspec1 = yspec_new(h, "tmp")) == NULL)
if ((yspec1 = yspec_new1(h, YANG_DOMAIN_TOP, "tmp")) == NULL)
goto done;
xmsd = NULL;
while ((xmsd = xml_child_each(xmodfile, xmsd, CX_ELMNT)) != NULL) {

View file

@ -639,7 +639,7 @@ clicon_options_main(clixon_handle h)
char *yangspec = "clixon-config";
/* Create configure yang-spec */
if ((yspec = yspec_new(h, YANG_CONFIG_TOP)) == NULL)
if ((yspec = yspec_new1(h, YANG_DOMAIN_TOP, YANG_CONFIG_TOP)) == NULL)
goto done;
/*
* Set configure file if not set by command-line above

View file

@ -260,6 +260,8 @@ yang_argument_set(yang_stmt *ys,
*
* @param[in] ys Yang statement node
* @param[in] arg Argument, is copied
* @retval 0 Ok
* @retval -1 Error
*/
int
yang_argument_dup(yang_stmt *ys,
@ -829,27 +831,53 @@ yang_stats(yang_stmt *yt,
/* stats end */
/*! Create new yang specification, addd as child to top-level yang_mounts
/*! Create new yang specification for top domain, add as child to top-level yang_mounts
*
* @retval yspec Free with ys_free()
* @retval NULL Error
* @param[in] h Clixon handle
* @param[in] domain Yang domain
* @param[in] name Yang spec name
* @retval yspec Yang spec, free with ys_free
* @retval NULL Error
* XXX Backward-compatible 7.1
*/
yang_stmt *
yspec_new(clixon_handle h,
char *name)
{
return yspec_new1(h, YANG_DOMAIN_TOP, name);
}
/*! Create new yang specification, addd as child to top-level yang_mounts
*
* @param[in] h Clixon handle
* @param[in] domain Yang domain
* @param[in] name Yang spec name
* @retval yspec Yang spec, free with ys_free
* @retval NULL Error
* @see yspec_new Hardcoded to top-domain
*/
yang_stmt *
yspec_new1(clixon_handle h,
char *domain,
char *name)
{
yang_stmt *ymounts;
yang_stmt *ydomain;
yang_stmt *yspec;
if ((ymounts = clixon_yang_mounts_get(h)) == NULL){
clixon_err(OE_YANG, 0, "Yang-mounts not created");
goto done;
}
if ((ydomain = yang_find(ymounts, Y_DOMAIN, domain)) == NULL){
clixon_err(OE_YANG, 0, "Yang domain %s not found", domain);
goto done;
}
if ((yspec = ys_new(Y_SPEC)) == NULL)
goto done;
if (yang_argument_dup(yspec, name) < 0)
if (name != NULL && yang_argument_dup(yspec, name) < 0)
goto done;
if (yn_insert(ymounts, yspec) < 0)
if (yn_insert(ydomain, yspec) < 0)
goto done;
return yspec;
done:
@ -876,7 +904,8 @@ yspec_new_shared(clixon_handle h,
yspec1 = yspec0;
}
else {
if ((yspec1 = yspec_new(h, domain)) == NULL)
// XXX domain used as name
if ((yspec1 = yspec_new1(h, domain, domain)) == NULL)
goto done;
yang_flag_set(yspec1, YANG_FLAG_SPEC_MOUNT);
clixon_debug(CLIXON_DBG_YANG, "new yang-spec: %p", yspec1);
@ -889,6 +918,39 @@ yspec_new_shared(clixon_handle h,
return yspec1;
}
/*! Create new yang domain
*
* @param[in] h Clixon handle
* @param[in] domain Yang domain name
* @retval ydomain Yang spec, free with ys_free
* @retval NULL Error
*/
yang_stmt *
ydomain_new(clixon_handle h,
char *domain)
{
yang_stmt *ymounts;
yang_stmt *ydomain;
if (domain == NULL){
clixon_err(OE_YANG, EINVAL, "domain is NULL");
goto done;
}
if ((ymounts = clixon_yang_mounts_get(h)) == NULL){
clixon_err(OE_YANG, 0, "Yang-mounts not created");
goto done;
}
if ((ydomain = ys_new(Y_DOMAIN)) == NULL)
goto done;
if (yang_argument_dup(ydomain, domain) < 0)
goto done;
if (yn_insert(ymounts, ydomain) < 0)
goto done;
return ydomain;
done:
return NULL;
}
/*! Create new yang node/statement given size
*
* Size parameter for variable size, eg extended YANG struct
@ -2156,10 +2218,10 @@ ys_real_module(yang_stmt *ys,
return retval;
}
/*! Find top of tree, the yang specification from within the tree
/*! Find spec tree, the yang specification from within the tree
*
* @param[in] ys Any yang statement in a yang tree
* @retval yspec The top yang specification
* @retval yspec The yang specification
* @see ys_module
* @see yang_augment_node where shortcut is set for augment
* @see yang_myroot for first node under (sub)module
@ -2177,6 +2239,21 @@ ys_spec(yang_stmt *ys)
return ys;
}
/*! Find domain tree,
*
* @param[in] ys Any yang statement in a yang tree
* @retval ydomain The yang domain specification
*/
yang_stmt *
ys_domain(yang_stmt *ys)
{
yang_stmt *yn;
if ((yn = ys_spec(ys)) != NULL)
return yn->ys_parent;
return NULL;
}
/*! Find top of tree, the yang specification from within the tree
*
* @param[in] ys Any yang statement in a yang tree
@ -2296,8 +2373,10 @@ int
yang_mounts_print(FILE *f,
yang_stmt *ymounts)
{
yang_stmt *ydomain;
yang_stmt *yspec;
int inext;
int inext2;
cg_var *cv;
cvec *cvv;
@ -2306,15 +2385,19 @@ yang_mounts_print(FILE *f,
return -1;
}
inext = 0;
while ((yspec = yn_iter(ymounts, &inext)) != NULL) {
fprintf(f, " %s\n", yang_argument_get(yspec));
if ((cv = yang_cv_get(yspec)) != NULL){
cv_print(f, yang_cv_get(yspec));
fprintf(f, "\n");
}
if ((cvv = yang_cvec_get(yspec)) != NULL){
cvec_print(f, cvv);
fprintf(f, "\n");
while ((ydomain = yn_iter(ymounts, &inext)) != NULL) {
fprintf(f, "domain:%s\n", yang_argument_get(ydomain));
inext2 = 0;
while ((yspec = yn_iter(ydomain, &inext2)) != NULL) {
fprintf(f, " spec:%s\n", yang_argument_get(yspec));
if ((cv = yang_cv_get(yspec)) != NULL){
cv_print(f, yang_cv_get(yspec));
fprintf(f, "\n");
}
if ((cvv = yang_cvec_get(yspec)) != NULL){
cvec_print(f, cvv);
fprintf(f, "\n");
}
}
}
return 0;
@ -4486,6 +4569,8 @@ yang_init(clixon_handle h)
goto done;
if (clixon_yang_mounts_set(h, ymounts) < 0)
goto done;
if (ydomain_new(h, YANG_DOMAIN_TOP) == NULL)
goto done;
retval = 0;
done:
return retval;

View file

@ -197,20 +197,28 @@ yang_mount_get(yang_stmt *ys,
{
int retval = 1;
yang_stmt *ymounts;
yang_stmt *ydomain;
yang_stmt *yspec = NULL;
int inext;
int inext2;
if ((ymounts = ys_mounts(ys)) == NULL){
clixon_err(OE_YANG, ENOENT, "Top-level yang mounts not found");
goto done;
}
inext = 0;
while ((yspec = yn_iter(ymounts, &inext)) != NULL) {
if (yang_keyword_get(yspec) != Y_SPEC ||
yang_cvec_get(yspec) == NULL ||
yang_flag_get(yspec, YANG_FLAG_SPEC_MOUNT) == 0)
continue;
if (xpath == NULL || cvec_find(yang_cvec_get(yspec), xpath) != NULL)
ydomain = NULL;
while ((ydomain = yn_iter(ymounts, &inext)) != NULL) {
inext2 = 0;
while ((yspec = yn_iter(ydomain, &inext2)) != NULL) {
if (yang_keyword_get(yspec) != Y_SPEC ||
yang_cvec_get(yspec) == NULL ||
yang_flag_get(yspec, YANG_FLAG_SPEC_MOUNT) == 0)
continue;
if (xpath == NULL || cvec_find(yang_cvec_get(yspec), xpath) != NULL)
break;
}
if (yspec != NULL)
break;
}
*yspecp = yspec;
@ -712,6 +720,7 @@ yang_schema_yanglib_parse_mount(clixon_handle h,
cxobj *xyanglib = NULL;
cxobj *xb;
yang_stmt *ymounts;
yang_stmt *ydomain;
yang_stmt *yspec0 = NULL;
yang_stmt *yspec1 = NULL;
char *xpath = NULL;
@ -742,7 +751,11 @@ yang_schema_yanglib_parse_mount(clixon_handle h,
clixon_err(OE_YANG, ENOENT, "Top-level yang mounts not found");
goto done;
}
yspec0 = yang_find(ymounts, Y_SPEC, domain);
if ((ydomain = yang_find(ymounts, Y_DOMAIN, domain)) == NULL){
if ((ydomain = ydomain_new(h, domain)) == NULL)
goto done;
}
yspec0 = yang_find(ydomain, Y_SPEC, domain); // XXX name?
if ((yspec1 = yspec_new_shared(h, xpath, domain, yspec0)) < 0)
goto done;
/* Either yspec0 = NULL and yspec1 is new, or yspec0 == yspec1 != NULL (shared) */