session CHANGE libyang context checking
Always check whether the context includes
everything and if not, try to correct
the situation. not only on new contexts.
diff --git a/src/session.c b/src/session.c
index 8dfa00b..af65377 100644
--- a/src/session.c
+++ b/src/session.c
@@ -164,8 +164,9 @@
return 0;
}
+/* SCHEMAS_DIR not used */
static int
-ctx_load_model(struct nc_session *session, const char *cpblt)
+ctx_check_and_load_model(struct nc_session *session, const char *cpblt)
{
const struct lys_module *module;
char *ptr, *ptr2;
@@ -243,13 +244,22 @@
return 0;
}
+/* SCHEMAS_DIR used */
static int
-ctx_load_ietf_netconf(struct ly_ctx *ctx, const char **cpblts)
+ctx_check_and_load_ietf_netconf(struct ly_ctx *ctx, const char **cpblts, int from_file)
{
int i;
const struct lys_module *ietfnc;
- if (!(ietfnc = ly_ctx_load_module(ctx, "ietf-netconf", NULL))) {
+ ietfnc = ly_ctx_get_module(ctx, "ietf-netconf", NULL);
+ if (!ietfnc) {
+ if (from_file) {
+ ietfnc = lys_parse_path(ctx, SCHEMAS_DIR"/ietf-netconf.yin", LYS_IN_YIN);
+ } else {
+ ietfnc = ly_ctx_load_module(ctx, "ietf-netconf", NULL);
+ }
+ }
+ if (!ietfnc) {
ERR("Loading base NETCONF schema failed.");
return 1;
}
@@ -323,11 +333,10 @@
return model_data;
}
-/* session with an empty context is assumed */
int
-nc_ctx_fill(struct nc_session *session)
+nc_ctx_check_and_fill(struct nc_session *session)
{
- int i;
+ int i, get_schema_support = 0;
ly_module_clb old_clb = NULL;
void *old_data = NULL;
@@ -336,21 +345,27 @@
/* check if get-schema is supported */
for (i = 0; session->cpblts[i]; ++i) {
if (!strncmp(session->cpblts[i], "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring", 51)) {
- /* it is supported, load local ietf-netconf-monitoring so we can create <get-schema> RPCs */
- if (ly_ctx_load_module(session->ctx, "ietf-netconf-monitoring", NULL)) {
- /* set module retrieval using <get-schema> */
- old_clb = ly_ctx_get_module_clb(session->ctx, &old_data);
- ly_ctx_set_module_clb(session->ctx, &libyang_module_clb, session);
- } else {
- WRN("Loading NETCONF monitoring schema failed, cannot use <get-schema>.");
- }
+ get_schema_support = 1;
break;
}
}
+ /* get-schema is supported, load local ietf-netconf-monitoring so we can create <get-schema> RPCs */
+ if (get_schema_support && !ly_ctx_get_module(session->ctx, "ietf-netconf-monitoring", NULL)) {
+ if (lys_parse_path(session->ctx, SCHEMAS_DIR"/ietf-netconf-monitoring.yin", LYS_IN_YIN)) {
+ /* set module retrieval using <get-schema> */
+ old_clb = ly_ctx_get_module_clb(session->ctx, &old_data);
+ ly_ctx_set_module_clb(session->ctx, &libyang_module_clb, session);
+ } else {
+ WRN("Loading NETCONF monitoring schema failed, cannot use <get-schema>.");
+ }
+ }
+
/* load base model disregarding whether it's in capabilities (but NETCONF capabilities are used to enable features) */
- if (ctx_load_ietf_netconf(session->ctx, session->cpblts)) {
- ly_ctx_set_module_clb(session->ctx, old_clb, old_data);
+ if (ctx_check_and_load_ietf_netconf(session->ctx, session->cpblts, !get_schema_support)) {
+ if (old_clb) {
+ ly_ctx_set_module_clb(session->ctx, old_clb, old_data);
+ }
return 1;
}
@@ -361,23 +376,12 @@
continue;
}
- ctx_load_model(session, session->cpblts[i]);
+ ctx_check_and_load_model(session, session->cpblts[i]);
}
- ly_ctx_set_module_clb(session->ctx, old_clb, old_data);
- return 0;
-}
-
-int
-nc_ctx_check(struct nc_session *session)
-{
- /* check presence of the required base schema */
- if (!ly_ctx_get_module(session->ctx, "ietf-netconf", NULL)) {
- if (ctx_load_ietf_netconf(session->ctx, session->cpblts)) {
- return 1;
- }
+ if (old_clb) {
+ ly_ctx_set_module_clb(session->ctx, old_clb, old_data);
}
-
return 0;
}
@@ -419,15 +423,8 @@
}
session->status = NC_STATUS_RUNNING;
- /* check/fill libyang context */
- if (session->flags & NC_SESSION_SHAREDCTX) {
- if (nc_ctx_check(session)) {
- goto fail;
- }
- } else {
- if (nc_ctx_fill(session)) {
- goto fail;
- }
+ if (nc_ctx_check_and_fill(session)) {
+ goto fail;
}
return session;
diff --git a/src/session_p.h b/src/session_p.h
index 4b11012..7cf06ea 100644
--- a/src/session_p.h
+++ b/src/session_p.h
@@ -159,17 +159,7 @@
* @param[in] session Session to create the context for.
* @return 0 on success, non-zero on failure.
*/
-int nc_ctx_fill(struct nc_session *session);
-
-/**
- * @brief Check whether the libyang context in \p session is suitable for NETCONF use
- * meaning whether the ietf-netconf model is loaded.
- *
- * @param[in] session Session with the capabilities to be supported if loading ietf-netconf
- * explicitly.
- * @return 0 on success, non-zero on failure.
- */
-int nc_ctx_check(struct nc_session *session);
+int nc_ctx_check_and_fill(struct nc_session *session);
/**
* @brief Create and connect a socket.
diff --git a/src/session_ssh.c b/src/session_ssh.c
index cb8901d..22ae67a 100644
--- a/src/session_ssh.c
+++ b/src/session_ssh.c
@@ -944,15 +944,8 @@
}
session->status = NC_STATUS_RUNNING;
- /* check/fill libyang context */
- if (session->flags & NC_SESSION_SHAREDCTX) {
- if (nc_ctx_check(session)) {
- goto fail;
- }
- } else {
- if (nc_ctx_fill(session)) {
- goto fail;
- }
+ if (nc_ctx_check_and_fill(session)) {
+ goto fail;
}
/* store information into the dictionary */
@@ -1069,15 +1062,8 @@
}
session->status = NC_STATUS_RUNNING;
- /* check/fill libyang context */
- if (session->flags & NC_SESSION_SHAREDCTX) {
- if (nc_ctx_check(session)) {
- goto fail;
- }
- } else {
- if (nc_ctx_fill(session)) {
- goto fail;
- }
+ if (nc_ctx_check_and_fill(session)) {
+ goto fail;
}
/* store information into the dictionary */
@@ -1146,15 +1132,8 @@
}
new_session->status = NC_STATUS_RUNNING;
- /* check/fill libyang context */
- if (session->flags & NC_SESSION_SHAREDCTX) {
- if (nc_ctx_check(session)) {
- goto fail;
- }
- } else {
- if (nc_ctx_fill(session)) {
- goto fail;
- }
+ if (nc_ctx_check_and_fill(session)) {
+ goto fail;
}
/* store information into session and the dictionary */
diff --git a/src/session_tls.c b/src/session_tls.c
index e52f31f..3cf67b1 100644
--- a/src/session_tls.c
+++ b/src/session_tls.c
@@ -353,15 +353,8 @@
}
session->status = NC_STATUS_RUNNING;
- /* check/fill libyang context */
- if (session->flags & NC_SESSION_SHAREDCTX) {
- if (nc_ctx_check(session)) {
- goto fail;
- }
- } else {
- if (nc_ctx_fill(session)) {
- goto fail;
- }
+ if (nc_ctx_check_and_fill(session)) {
+ goto fail;
}
/* store information into session and the dictionary */
@@ -421,15 +414,8 @@
}
session->status = NC_STATUS_RUNNING;
- /* check/fill libyang context */
- if (session->flags & NC_SESSION_SHAREDCTX) {
- if (nc_ctx_check(session)) {
- goto fail;
- }
- } else {
- if (nc_ctx_fill(session)) {
- goto fail;
- }
+ if (nc_ctx_check_and_fill(session)) {
+ goto fail;
}
return session;