From 442e0391cc5a819f7ce14a673e435fe8740321e7 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Thu, 15 Aug 2024 18:43:45 +0200 Subject: [PATCH] Added YANG deviate flag to not follow orig links Fixed unbounded loop in deviation --- lib/clixon/clixon_yang.h | 1 + lib/src/clixon_yang.c | 6 +++-- lib/src/clixon_yang_module.c | 2 +- lib/src/clixon_yang_type.c | 10 ++++++- test/test_openconfig.sh | 52 +++++++++++++++++++++++++++++++++++- 5 files changed, 66 insertions(+), 5 deletions(-) diff --git a/lib/clixon/clixon_yang.h b/lib/clixon/clixon_yang.h index 4d915864..5ea5b340 100644 --- a/lib/clixon/clixon_yang.h +++ b/lib/clixon/clixon_yang.h @@ -94,6 +94,7 @@ * augment/grouping */ #define YANG_FLAG_MYMODULE 0x800 /* Use external map to access my-module for * UNKNOWNS and augment/grouping */ +#define YANG_FLAG_NOORIG 0x1000 /* Node different from orig, do not use orig-link */ /* * Types diff --git a/lib/src/clixon_yang.c b/lib/src/clixon_yang.c index 41899946..f2875739 100644 --- a/lib/src/clixon_yang.c +++ b/lib/src/clixon_yang.c @@ -2358,6 +2358,7 @@ yang_deviation(yang_stmt *ys, enum rfc_6020 kw; int min; int max; + int inext0; int inext; if (yang_keyword_get(ys) != Y_DEVIATION) @@ -2379,8 +2380,8 @@ yang_deviation(yang_stmt *ys, */ } /* Go through deviates of deviation */ - inext = 0; - while ((yd = yn_iter(ys, &inext)) != NULL) { + inext0 = 0; + while ((yd = yn_iter(ys, &inext0)) != NULL) { /* description / if-feature / reference */ if (yang_keyword_get(yd) != Y_DEVIATE) continue; @@ -2448,6 +2449,7 @@ yang_deviation(yang_stmt *ys, /* Make a copy of deviate child and insert. */ if ((yc1 = ys_dup(yc)) == NULL) goto done; + yang_flag_set(yc1, YANG_FLAG_NOORIG); if (yn_insert(ytarget, yc1) < 0) goto done; } diff --git a/lib/src/clixon_yang_module.c b/lib/src/clixon_yang_module.c index 1ec4de35..83718a43 100644 --- a/lib/src/clixon_yang_module.c +++ b/lib/src/clixon_yang_module.c @@ -924,7 +924,7 @@ yang_lib2yspec(clixon_handle h, if ((modmin = yang_len_get(yspec) - (1+veclen - modmin)) < 0) goto fail; if (yang_parse_post(h, yspec, modmin) < 0) - goto done; + goto fail; retval = 1; done: if (vec) diff --git a/lib/src/clixon_yang_type.c b/lib/src/clixon_yang_type.c index 857f5a9a..f8cedd21 100644 --- a/lib/src/clixon_yang_type.c +++ b/lib/src/clixon_yang_type.c @@ -1482,8 +1482,16 @@ yang_type_get(yang_stmt *ys, if (options) *options = 0x0; /* Use original tree to resolve types */ - if ((yorig = yang_orig_get(ys)) != NULL) { + if ((ytype = yang_find(ys, Y_TYPE, NULL)) == NULL){ + clixon_err(OE_DB, ENOENT, "mandatory type object is not found"); + goto done; + } + if ((yorig = yang_orig_get(ys)) != NULL && yang_flag_get(ytype, YANG_FLAG_NOORIG) == 0){ ys = yorig; + if ((ytype = yang_find(ys, Y_TYPE, NULL)) == NULL){ + clixon_err(OE_DB, ENOENT, "mandatory type object is not found"); + goto done; + } } /* Find mandatory type */ if ((ytype = yang_find(ys, Y_TYPE, NULL)) == NULL){ diff --git a/test/test_openconfig.sh b/test/test_openconfig.sh index 1dafb72e..90ec0e92 100755 --- a/test/test_openconfig.sh +++ b/test/test_openconfig.sh @@ -76,11 +76,61 @@ cat < $cfg EOF - new "$clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_FILE=$f show version" + new "$clixon_cli -D $DBG -1f $cfg -y $f show version" expectpart "$($clixon_cli -D $DBG -1f $cfg -y $f show version)" 0 "${CLIXON_VERSION}" fi done +# The following test is a special case: A deviation of a grouped type did not appear in +# type resolution +f=$dir/my.yang +cat < $f +module my { + namespace "urn:example:clixon"; + prefix "ex"; + + import "openconfig-network-instance" { + prefix "oc-netinst"; + } + deviation "/oc-netinst:network-instances/oc-netinst:network-instance/oc-netinst:protocols/oc-netinst:protocol/oc-netinst:isis/oc-netinst:interfaces/oc-netinst:interface/oc-netinst:levels/oc-netinst:level/oc-netinst:afi-safi/oc-netinst:af/oc-netinst:config/oc-netinst:metric" { + description "metric range is restricted"; + deviate "replace" { + type "union" { + type "uint32"; + type "enumeration" { + enum "MYTEXT"; + } + } + default "MYTEXT"; + } + } +} +EOF + +modname=$(basename $f | awk -F "." '{print $1}') +# Generate autocli for these modules +AUTOCLI=$(autocli_config openconfig-* kw-nokey false) + +cat < $cfg + + $cfg + ietf-netconf:startup + ${OPENCONFIG} + ${YANG_INSTALLDIR} + true + /usr/local/lib/$APPNAME/clispec + /usr/local/lib/$APPNAME/cli + $APPNAME + /usr/local/var/run/$APPNAME.sock + /usr/local/var/run/$APPNAME.pidfile + $dir + ${AUTOCLI} + +EOF + +new "deviation: $clixon_cli -D $DBG -1f $cfg -y $f show version" +expectpart "$($clixon_cli -D $DBG -1f $cfg -y $f show version)" 0 "${CLIXON_VERSION}" + rm -rf $dir new "endtest"