diff --git a/CHANGELOG.md b/CHANGELOG.md index 940c7943..bfaa7d48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,12 @@ Expected: February 2024 ### Minor features +* Optimization: + * Added mountpoint cache as yang flag `YANG_FLAG_MTPOINT_POTENTIAL` + * Optimized `yang_find`, especially namespace lookup + * Filtered state data if not match xpath * Added reference count for shared yang-specs (schema mounts) + * Allowed for sharing yspec+modules between several mountpoints ### Corrected Bugs diff --git a/apps/backend/backend_plugin.c b/apps/backend/backend_plugin.c index 0d30c33b..d8960e3c 100644 --- a/apps/backend/backend_plugin.c +++ b/apps/backend/backend_plugin.c @@ -393,10 +393,12 @@ clixon_plugin_statedata_all(clicon_handle h, /* XXX: only for state data and according to with-defaults setting */ if (xml_defaults_nopresence(x, 2) < 0) goto done; - if ((ret = netconf_trymerge(x, yspec, xret)) < 0) - goto done; - if (ret == 0) - goto fail; + if (xpath_first(x, nsc, "%s", xpath) != NULL){ + if ((ret = netconf_trymerge(x, yspec, xret)) < 0) + goto done; + if (ret == 0) + goto fail; + } if (x){ xml_free(x); x = NULL; diff --git a/lib/clixon/clixon_yang.h b/lib/clixon/clixon_yang.h index e1062596..b48ea23a 100644 --- a/lib/clixon/clixon_yang.h +++ b/lib/clixon/clixon_yang.h @@ -83,7 +83,14 @@ * leaf z; * } */ -#define YANG_FLAG_MOUNTPOINT 0x100 /* Mark node as ACTUAL populated mount-point +#define YANG_FLAG_MTPOINT_POTENTIAL 0x100 /* Mark node as POTENTIAL mount-point, ie it fulfils: + * - is CONTAINER or LIST, AND + * - has YANG schema mount "mount-point" as child element, AND + * - the extension label matches y (see note below) + * Set by ys_populate2 + * Read by yang_schema_mount_point + */ +#define YANG_FLAG_MOUNTPOINT 0x200 /* Mark node as ACTUAL populated mount-point * Set by yang_mount_set * Read by ys_free1 */ diff --git a/lib/clixon/clixon_yang_schema_mount.h b/lib/clixon/clixon_yang_schema_mount.h index 478bd410..2568be45 100644 --- a/lib/clixon/clixon_yang_schema_mount.h +++ b/lib/clixon/clixon_yang_schema_mount.h @@ -54,6 +54,7 @@ /* * Prototypes */ +int yang_schema_mount_point0(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); diff --git a/lib/src/clixon_yang.c b/lib/src/clixon_yang.c index 26ef7f38..d071ed4e 100644 --- a/lib/src/clixon_yang.c +++ b/lib/src/clixon_yang.c @@ -3017,6 +3017,7 @@ ys_populate2(yang_stmt *ys, { int retval = -1; clicon_handle h = (clicon_handle)arg; + int ret; switch(ys->ys_keyword){ case Y_LEAF: @@ -3033,6 +3034,11 @@ ys_populate2(yang_stmt *ys, default: break; } + /* RFC 8525 Yang schema mount flag for optimization */ + if ((ret = yang_schema_mount_point0(ys)) < 0) + goto done; + if (ret == 1) + yang_flag_set(ys, YANG_FLAG_MTPOINT_POTENTIAL); retval = 0; done: return retval; diff --git a/lib/src/clixon_yang_internal.h b/lib/src/clixon_yang_internal.h index 2bbda263..16fbd815 100644 --- a/lib/src/clixon_yang_internal.h +++ b/lib/src/clixon_yang_internal.h @@ -98,7 +98,7 @@ struct yang_stmt{ Y_TYPE & identity: store all derived types as : list Y_UNIQUE: vector of descendant schema node ids - Y_EXTENSION: vector of instantiated UNKNOWNSo + Y_EXTENSION: vector of instantiated UNKNOWNS Y_UNKNOWN: app-dep: yang-mount-points */ int ys_ref; /* Reference count for free, only YS_SPEC */ diff --git a/lib/src/clixon_yang_schema_mount.c b/lib/src/clixon_yang_schema_mount.c index 53bfa7e6..68f94354 100644 --- a/lib/src/clixon_yang_schema_mount.c +++ b/lib/src/clixon_yang_schema_mount.c @@ -102,7 +102,7 @@ * @note That this may be a restriction on the usage of "label". The RFC is somewhat unclear. */ int -yang_schema_mount_point(yang_stmt *y) +yang_schema_mount_point0(yang_stmt *y) { int retval = -1; enum rfc_6020 keyw; @@ -137,6 +137,14 @@ yang_schema_mount_point(yang_stmt *y) goto done; } +/*! Cached variant of yang_schema_mount_point + */ +int +yang_schema_mount_point(yang_stmt *y) +{ + return yang_flag_get(y, YANG_FLAG_MTPOINT_POTENTIAL) ? 1 : 0; +} + /*! Get yangspec mount-point * * @param[in] y Yang container/list containing unknown node @@ -431,6 +439,7 @@ find_schema_mounts(cxobj *x, * "ietf-yang-schema-mount" modules in the mounted schema and specifying * the schemas in exactly the same way as the top-level schema. * Alt: see snmp_yang2xml to get instances instead of brute force traverse of whole tree + * @note: Mountpoints must exist in xret on entry */ static int yang_schema_mount_statedata_yanglib(clicon_handle h, @@ -494,7 +503,7 @@ yang_schema_mount_statedata_yanglib(clicon_handle h, * * @param[in] h Clixon handle * @param[in] yspec Yang spec - * @param[in] xpath XML Xpath + * @param[in] xpath XML XPath * @param[in] nsc XML Namespace context for xpath * @param[in,out] xret Existing XML tree, merge x into this * @param[out] xerr XML error tree, if retval = 0 @@ -556,10 +565,12 @@ yang_schema_mount_statedata(clicon_handle h, goto done; if (ret == 0) goto fail; - if ((ret = netconf_trymerge(x1, yspec, xret)) < 0) - goto done; - if (ret == 0) - goto fail; + if (xpath_first(x1, nsc, "%s", xpath) != NULL){ + if ((ret = netconf_trymerge(x1, yspec, xret)) < 0) + goto done; + if (ret == 0) + goto fail; + } } /* Find mount-points and return yang-library state */ if (yang_schema_mount_statedata_yanglib(h, xpath, nsc, xret, xerr) < 0)