diff --git a/CHANGELOG.md b/CHANGELOG.md
index e1d121eb..e892b8f6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,6 @@
# Clixon Changelog
+* [6.1.0](#610) Expected: beginning of 2023
* [6.0.0](#600) 29 Nov 2022
* [5.9.0](#590) 24 September 2022
* [5.8.0](#580) 28 July 2022
@@ -37,6 +38,15 @@
* [3.3.2](#332) Aug 27 2017
* [3.3.1](#331) June 7 2017
+## 6.1.0
+Expected: beginning of 2023
+
+### Corrected Bugs
+
+* Fixed [Netconf monitoring](https://github.com/clicon/clixon/issues/370)
+ - Announce module capability
+ - Return origin Yang file in get-schema
+
## 6.0.0
29 Nov 2022
diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c
index aa85374e..093b8c3d 100644
--- a/apps/backend/backend_client.c
+++ b/apps/backend/backend_client.c
@@ -1064,18 +1064,20 @@ from_client_get_schema(clicon_handle h,
void *arg,
void *regarg)
{
- int retval = -1;
- cxobj *x; /* Generic xml tree */
- cvec *nsc = NULL;
- char *identifier = NULL;
- char *version = NULL;
- char *format = NULL;
- yang_stmt *yspec;
- yang_stmt *ymod;
- yang_stmt *ymatch;
- yang_stmt *yrev;
- cbuf *cbyang = NULL;
-
+ int retval = -1;
+ cxobj *x; /* Generic xml tree */
+ cvec *nsc = NULL;
+ char *identifier = NULL;
+ char *version = NULL;
+ char *format = NULL;
+ yang_stmt *yspec;
+ yang_stmt *ymod;
+ yang_stmt *ymatch;
+ yang_stmt *yrev;
+ cbuf *cbyang = NULL;
+ cbuf *cbmsg = NULL;
+ const char *filename;
+
if ((yspec = clicon_dbspec_yang(h)) == NULL){
clicon_err(OE_YANG, ENOENT, "No yang spec");
goto done;
@@ -1121,12 +1123,25 @@ from_client_get_schema(clicon_handle h,
ymatch = ymod;
}
if (ymatch == NULL){
- if (netconf_invalid_value(cbret, "protocol", "No such schema") < 0)
+ if ((cbmsg = cbuf_new()) == NULL){
+ clicon_err(OE_XML, errno, "cbuf_new");
+ goto done;
+ }
+ if (version)
+ cprintf(cbmsg, "No schema matching: %s@%s", identifier, version);
+ else
+ cprintf(cbmsg, "No schema matching: %s", identifier);
+ if (netconf_invalid_value(cbret, "protocol", cbuf_get(cbmsg)) < 0)
goto done;
goto ok;
}
if (format && strcmp(format, "yang") != 0){
- if (netconf_invalid_value(cbret, "protocol", "Format not supported") < 0)
+ if ((cbmsg = cbuf_new()) == NULL){
+ clicon_err(OE_XML, errno, "cbuf_new");
+ goto done;
+ }
+ cprintf(cbmsg, "Format not supported: %s", format);
+ if (netconf_invalid_value(cbret, "protocol", cbuf_get(cbmsg)) < 0)
goto done;
goto ok;
}
@@ -1136,12 +1151,17 @@ from_client_get_schema(clicon_handle h,
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
- yang_print_cbuf(cbyang, ymatch, 0, 0);
+ if ((filename = yang_filename_get(ymatch)) != NULL){
+ if (clicon_file_cbuf(filename, cbyang) < 0)
+ goto done;
+ }
xml_chardata_cbuf_append(cbret, cbuf_get(cbyang));
cprintf(cbret, "");
ok:
retval = 0;
done:
+ if (cbmsg)
+ cbuf_free(cbmsg);
if (cbyang)
cbuf_free(cbyang);
if (nsc)
diff --git a/lib/clixon/clixon_file.h b/lib/clixon/clixon_file.h
index 195522ac..62feb2e6 100644
--- a/lib/clixon/clixon_file.h
+++ b/lib/clixon/clixon_file.h
@@ -42,9 +42,8 @@
int clicon_file_dirent(const char *dir, struct dirent **ent,
const char *regexp, mode_t type);
-
int clicon_files_recursive(const char *dir, const char *regexp, cvec *cvv);
-
int clicon_file_copy(char *src, char *target);
+int clicon_file_cbuf(const char *filename, cbuf *cb);
#endif /* _CLIXON_FILE_H_ */
diff --git a/lib/src/clixon_file.c b/lib/src/clixon_file.c
index 83731c11..eec717e8 100644
--- a/lib/src/clixon_file.c
+++ b/lib/src/clixon_file.c
@@ -160,9 +160,9 @@ clicon_files_recursive(const char *dir,
}
/*! Return alphabetically sorted files from a directory matching regexp
+ *
* @param[in] dir Directory path
* @param[out] ent Entries pointer, will be filled in with dir entries. Free
- * after use
* @param[in] regexp Regexp filename matching
* @param[in] type File type matching, see stat(2)
*
@@ -262,8 +262,11 @@ quit:
}
/*! Make a copy of file src. Overwrite existing
- * @retval 0 OK
- * @retval -1 Error
+ *
+ * @param[in] src Source filename
+ * @param[out] target Destination filename
+ * @retval 0 OK
+ * @retval -1 Error
*/
int
clicon_file_copy(char *src,
@@ -304,3 +307,43 @@ clicon_file_copy(char *src,
errno = err;
return retval;
}
+
+/*! Read content of file into cbuf
+ *
+ * @param[in] filename
+ * @param[out] cb
+ * @retval 0 OK
+ * @retval -1 Error
+ */
+int
+clicon_file_cbuf(const char *filename,
+ cbuf *cb)
+{
+ int retval = -1;
+ int fd = 0;
+ int err = 0;
+ char line[512];
+ int bytes;
+ struct stat st;
+
+ if (stat(filename, &st) != 0){
+ clicon_err(OE_UNIX, errno, "stat");
+ return -1;
+ }
+ if ((fd = open(filename, O_RDONLY)) == -1) {
+ clicon_err(OE_UNIX, errno, "open(%s) for read", filename);
+ return -1;
+ }
+ while((bytes = read(fd, line, sizeof(line))) > 0)
+ if (cbuf_append_buf(cb, line, bytes) < 0){
+ clicon_err(OE_UNIX, errno, "cbuf_append_buf(%s)", filename);
+ err = errno;
+ goto error;
+ }
+ retval = 0;
+ error:
+ close(fd);
+ if (retval < 0)
+ errno = err;
+ return retval;
+}
diff --git a/lib/src/clixon_netconf_lib.c b/lib/src/clixon_netconf_lib.c
index 369e56b9..5fa4b94f 100644
--- a/lib/src/clixon_netconf_lib.c
+++ b/lib/src/clixon_netconf_lib.c
@@ -1815,6 +1815,11 @@ netconf_capabilites(clicon_handle h,
cprintf(cb, "");
/* RFC5277 Notification Capability */
cprintf(cb, "%s", NETCONF_NOTIFICATION_CAPABILITY);
+ /* RFC6022 YANG Module for NETCONF Monitoring
+ * This seems non-standard but necessary for most existing boxes and software
+ */
+ if (clicon_option_bool(h, "CLICON_NETCONF_MONITORING"))
+ cprintf(cb, "%s", NETCONF_MONITORING_NAMESPACE);
/* It is somewhat arbitrary why some features/capabilities are hardocded and why some are not
* rfc 6241 Sec 8.4 confirmed-commit capabilities */
diff --git a/test/test_netconf_monitoring.sh b/test/test_netconf_monitoring.sh
index 297f92ae..e3ffb7bc 100755
--- a/test/test_netconf_monitoring.sh
+++ b/test/test_netconf_monitoring.sh
@@ -54,7 +54,7 @@ new "wait backend"
wait_backend
new "Retrieving all state via operation"
-expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "urn:ietf:params:netconf:base:1.0urn:ietf:params:netconf:base:1.1.*.*" ""
+expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "urn:ietf:params:netconf:base:1.0urn:ietf:params:netconf:base:1.1.*urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring.*.*"
# 4.1. Retrieving Schema List via Operation
new "Retrieving Schema List via Operation"
@@ -63,30 +63,29 @@ expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "
# 4.2. Retrieving Schema Instances
# From 2b. bar, version 2008-06-1 in YANG format, via get-schema
new "Retrieving clixon-example schema instance using id, version, format"
-expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2022-01-01yang" "module clixon-example {yang-version 1.1;namespace urn:example:clixon;prefix ex;revision 2022-01-01;}"
+expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2022-01-01yang" "module clixon-example{"
new "Retrieving clixon-example schema instance using id, version only"
-expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2022-01-01" "module clixon-example {yang-version 1.1;namespace urn:example:clixon;prefix ex;revision 2022-01-01;}"
+expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2022-01-01" "module clixon-example{"
new "Retrieving clixon-example schema instance using id only"
-expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example" "module clixon-example {yang-version 1.1;namespace urn:example:clixon;prefix ex;revision 2022-01-01;}"
+expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example" "module clixon-example{"
new "Retrieving ietf-inet-types schema"
-expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "ietf-inet-types" "module ietf-inet-types {namespace urn:ietf:params:xml:ns:yang:ietf-
-inet-types;prefix inet"
+expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "ietf-inet-types" "module ietf-inet-types {"
# Negative tests
new "get-schema: no id"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "applicationmissing-elementidentifiererrorMandatory variable of get-schema in module ietf-netconf-monitoring"
new "get-schema: non-existing schema"
-expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "not-found" "protocolinvalid-valueerrorNo such schema"
+expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "not-found" "protocolinvalid-valueerrorNo schema matching: not-found"
new "get-schema: non-existing format"
-expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2022-01-01xsd" "protocolinvalid-valueerrorFormat not supported"
+expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2022-01-01xsd" "protocolinvalid-valueerrorFormat not supported: xsd"
new "get-schema: non-existing date"
-expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2013-01-01yang" "protocolinvalid-valueerrorNo such schema"
+expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2013-01-01yang" "protocolinvalid-valueerrorNo schema matching: clixon-example@2013-01-01"
if [ $BE -ne 0 ]; then
new "Kill backend"
diff --git a/test/test_netconf_monitoring_multiple.sh b/test/test_netconf_monitoring_multiple.sh
index 79c7c7a2..01b00764 100755
--- a/test/test_netconf_monitoring_multiple.sh
+++ b/test/test_netconf_monitoring_multiple.sh
@@ -87,10 +87,10 @@ new "get-schema: multiple schemas, fail"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example" "applicationoperation-faileddata-not-uniqueerror"
new "get-schema: multiple schemas 2000-01-01"
-expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2000-01-01" "module clixon-example {yang-version 1.1;namespace urn:example:clixon;prefix ex;revision 2000-01-01;}"
+expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2000-01-01" "module clixon-example{"
new "get-schema: multiple schemas 2022-01-01"
-expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2022-01-01" "module clixon-example {yang-version 1.1;namespace urn:example:clixon;prefix ex;revision 2022-01-01;}"
+expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "clixon-example2022-01-01" "module clixon-example{"
if [ $BE -ne 0 ]; then
new "Kill backend"
diff --git a/test/test_netconf_ssh_callhome.sh b/test/test_netconf_ssh_callhome.sh
index e25f87f4..050fbcee 100755
--- a/test/test_netconf_ssh_callhome.sh
+++ b/test/test_netconf_ssh_callhome.sh
@@ -144,7 +144,7 @@ EOF
new "Start Listener client"
echo "ssh -s -F $sshcfg -v -i $key -o ProxyUseFdpass=yes -o ProxyCommand=\"clixon_netconf_ssh_callhome_client -a 127.0.0.1\" . netconf"
#-F $sshcfg
-expectpart "$(ssh -s -F $sshcfg -v -i $key -o ProxyUseFdpass=yes -o ProxyCommand="${clixon_netconf_ssh_callhome_client} -a 127.0.0.1" . netconf < $rpccmd)" 0 "urn:ietf:params:netconf:base:1.1urn:ietf:params:netconf:base:1.0urn:ietf:params:netconf:capability:yang-library:1.0?revision=2019-01-04&module-set-id=42urn:ietf:params:netconf:capability:candidate:1.0urn:ietf:params:netconf:capability:validate:1.1urn:ietf:params:netconf:capability:xpath:1.0urn:ietf:params:netconf:capability:with-defaults:1.0?basic-mode=explicit&also-supported=report-all,trim,report-all-taggedurn:ietf:params:netconf:capability:notification:1.02" ""
+expectpart "$(ssh -s -F $sshcfg -v -i $key -o ProxyUseFdpass=yes -o ProxyCommand="${clixon_netconf_ssh_callhome_client} -a 127.0.0.1" . netconf < $rpccmd)" 0 "urn:ietf:params:netconf:base:1.1.*2" ""
# Wait
wait