diff --git a/CHANGELOG.md b/CHANGELOG.md index 332576b3..49759dea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -86,6 +86,7 @@ Developers may need to change their code ### Minor changes +* Augment target node check strict, instead of printing a warning, it will terminate with error. * Implemented: [Simplifying error messages for regex validations. #174](https://github.com/clicon/clixon/issues/174) * Add ca_reset plugin also when backend starts as `-s none` * Corrected client session handling to make internal IPC socket persistent @@ -113,6 +114,9 @@ Developers may need to change their code ### Corrected Bugs +* Fixed: [Augment that reference a submodule as target node fails #178](https://github.com/clicon/clixon/issues/178) +* Fixed a memory error that was reported in slack by Pawel Maslanka + * The crash printout was: `realloc(): invalid next size Aborted` * Fixed: [Irregular ordering of cli command + help text when integer is a part of command #176](https://github.com/clicon/clixon/issues/176) * Enabled by default `cligen_lexicalorder_set()` using strversmp instead of strcmp * Fixed: [xml bind yang error in xml_bind_yang_rpc_reply #175](https://github.com/clicon/clixon/issues/175) diff --git a/apps/backend/backend_main.c b/apps/backend/backend_main.c index 1e95d963..c030e196 100644 --- a/apps/backend/backend_main.c +++ b/apps/backend/backend_main.c @@ -1011,7 +1011,8 @@ main(int argc, /* Start session-id for clients */ clicon_session_id_set(h, 0); - if (clicon_debug_get() && + /* Enable this to get prints of datastore and session status */ + if (0 && clicon_debug_get() && backend_timer_setup(0, h) < 0) goto done; if (stream_timer_setup(0, h) < 0) diff --git a/apps/restconf/restconf_main_evhtp.c b/apps/restconf/restconf_main_evhtp.c index f921f374..541ba13c 100644 --- a/apps/restconf/restconf_main_evhtp.c +++ b/apps/restconf/restconf_main_evhtp.c @@ -695,7 +695,7 @@ usage(clicon_handle h, fprintf(stderr, "usage:%s [options]\n" "where options are\n" "\t-h \t\t Help\n" - "\t-D \t Debug level\n" + "\t-D \t Debug level _ overrides any config debug setting\n" "\t-f \t Configuration file (mandatory)\n" "\t-E \t Extra configuration file directory\n" "\t-l > \t Log on (s)yslog, (f)ile (syslog is default)\n" @@ -923,6 +923,7 @@ cx_evhtp_socket(clicon_handle h, * @param[in] xconfig XML config * @param[in] nsc Namespace context * @param[in] eh Evhtp handle + * @param[in] dbg0 Manually set debug flag, if set overrides configuration setting * @retval -1 Error * @retval 0 OK, but restconf disabled, proceed with other if possible * @retval 1 OK @@ -931,7 +932,8 @@ static int cx_evhtp_init(clicon_handle h, cxobj *xrestconf, cvec *nsc, - cx_evhtp_handle *eh) + cx_evhtp_handle *eh, + int dbg0) { int retval = -1; int ssl_enable = 0; @@ -962,7 +964,9 @@ cx_evhtp_init(clicon_handle h, server_key_path = xml_body(x); if ((x = xpath_first(xrestconf, nsc, "server-ca-cert-path")) != NULL) server_ca_cert_path = xml_body(x); - if ((x = xpath_first(xrestconf, nsc, "debug")) != NULL && + /* Only set debug from config if not set manually */ + if (dbg0 == 0 && + (x = xpath_first(xrestconf, nsc, "debug")) != NULL && (bstr = xml_body(x)) != NULL){ dbg = atoi(bstr); clicon_debug_init(dbg, NULL); @@ -1022,12 +1026,14 @@ cx_evhtp_init(clicon_handle h, * That is, EITHER local config OR read config from backend once * @param[in] h Clicon handle * @param[in] eh Clixon's evhtp handle + * @param[in] dbg0 Manually set debug flag, if set overrides configuration setting * @retval 0 OK * @retval -1 Error */ int restconf_config(clicon_handle h, - cx_evhtp_handle *eh) + cx_evhtp_handle *eh, + int dbg) { int retval = -1; char *dir; @@ -1139,7 +1145,7 @@ restconf_config(clicon_handle h, /* First try to get restconf config from local config-file */ if ((xrestconf1 = clicon_conf_restconf(h)) != NULL){ /* Initialize evhtp with local config: ret 0 means disabled -> need to query remote */ - if ((ret = cx_evhtp_init(h, xrestconf1, NULL, eh)) < 0) + if ((ret = cx_evhtp_init(h, xrestconf1, NULL, eh, dbg)) < 0) goto done; if (ret == 1) configure_done = 1; @@ -1175,7 +1181,7 @@ restconf_config(clicon_handle h, /* Extract restconf configuration */ if ((xrestconf2 = xpath_first(xconfig2, nsc, "restconf")) != NULL){ /* Initialize evhtp with config from backend */ - if ((ret = cx_evhtp_init(h, xrestconf2, nsc, eh)) < 0) + if ((ret = cx_evhtp_init(h, xrestconf2, nsc, eh, dbg)) < 0) goto done; if (ret == 1) configure_done = 1; @@ -1221,7 +1227,7 @@ main(int argc, case 'h': usage(h, argv0); break; - case 'D' : /* debug */ + case 'D' : /* debug. Note this overrides any setting in the config */ if (sscanf(optarg, "%d", &dbg) != 1) usage(h, argv0); break; @@ -1339,7 +1345,7 @@ main(int argc, _EVHTP_HANDLE = eh; /* global */ /* Read config */ - if (restconf_config(h, eh) < 0) + if (restconf_config(h, eh, dbg) < 0) goto done; /* Drop privileges after evhtp and server key/cert read */ if (drop_privileges){ diff --git a/lib/clixon/clixon_yang.h b/lib/clixon/clixon_yang.h index d9e76ca8..fa4bef0b 100644 --- a/lib/clixon/clixon_yang.h +++ b/lib/clixon/clixon_yang.h @@ -181,7 +181,7 @@ typedef int (yang_applyfn_t)(yang_stmt *ys, void *arg); * leaf, leaf-list, list, choice, case, rpc, input, output, * notification, anydata, and anyxml. */ -#define yang_schemanode(y) (yang_datanode(y) || yang_keyword_get(y) == Y_RPC || yang_keyword_get(y) == Y_CHOICE || yang_keyword_get(y) == Y_CASE || yang_keyword_get(y) == Y_INPUT || yang_keyword_get(y) == Y_OUTPUT || yang_keyword_get(y) == Y_NOTIFICATION) +#define yang_schemanode(y) (yang_datanode(y) || yang_keyword_get(y) == Y_RPC || yang_keyword_get(y) == Y_CHOICE || yang_keyword_get(y) == Y_CASE || yang_keyword_get(y) == Y_INPUT || yang_keyword_get(y) == Y_OUTPUT || yang_keyword_get(y) == Y_NOTIFICATION || yang_keyword_get(y) == Y_ACTION) /* * Prototypes diff --git a/lib/src/clixon_yang.c b/lib/src/clixon_yang.c index 1ce5f149..dac35031 100644 --- a/lib/src/clixon_yang.c +++ b/lib/src/clixon_yang.c @@ -97,6 +97,7 @@ static int yang_search_index_extension(clicon_handle h, yang_stmt *yext, yang_st * Here is also the place where doc on some types store variables (cv) */ static const map_str2int ykmap[] = { + {"action", Y_ACTION}, {"anydata", Y_ANYDATA}, {"anyxml", Y_ANYXML}, {"argument", Y_ARGUMENT}, @@ -497,12 +498,15 @@ ys_prune(yang_stmt *yp, if (i >= yp->ys_len) goto done; - size = (yp->ys_len - i - 1)*sizeof(struct yang_stmt *); yc = yp->ys_stmt[i]; - memmove(&yp->ys_stmt[i], - &yp->ys_stmt[i+1], - size); - yp->ys_stmt[yp->ys_len--] = NULL; + if (i < yp->ys_len - 1){ + size = (yp->ys_len - i - 1)*sizeof(struct yang_stmt *); + memmove(&yp->ys_stmt[i], + &yp->ys_stmt[i+1], + size); + } + yp->ys_len--; + yp->ys_stmt[yp->ys_len] = NULL; done: return yc; } @@ -931,10 +935,16 @@ yang_find_schemanode(yang_stmt *yn, for (i=0; iys_len; i++){ ys = yn->ys_stmt[i]; - if (ys->ys_keyword == Y_CHOICE){ /* Look for its children */ + if (yang_keyword_get(ys) == Y_CHOICE){ + /* First check choice itself */ + if (ys->ys_argument && strcmp(argument, ys->ys_argument) == 0){ + ysmatch = ys; + goto match; + } + /* Then look for its children (case) */ for (j=0; jys_len; j++){ yc = ys->ys_stmt[j]; - if (yc->ys_keyword == Y_CASE) /* Look for its children */ + if (yang_keyword_get(yc) == Y_CASE) /* Look for its children */ ysmatch = yang_find_schemanode(yc, argument); else if (yang_schemanode(yc)){ @@ -950,7 +960,9 @@ yang_find_schemanode(yang_stmt *yn, } /* Y_CHOICE */ else if (yang_schemanode(ys)){ - if (argument == NULL) + if (yang_keyword_get(ys) == Y_INPUT || yang_keyword_get(ys) == Y_OUTPUT) + ysmatch = ys; + else if (argument == NULL) ysmatch = ys; else if (ys->ys_argument && strcmp(argument, ys->ys_argument) == 0) @@ -1070,7 +1082,7 @@ yang_find_prefix_by_namespace(yang_stmt *ys, yang_stmt *yimport; yang_stmt *yprefix; - clicon_debug(1, "%s", __FUNCTION__); + clicon_debug(2, "%s", __FUNCTION__); /* First check if namespace is my own module */ myns = yang_find_mynamespace(ys); if (strcmp(myns, ns) == 0){ @@ -2559,7 +2571,6 @@ schema_nodeid_iterate(yang_stmt *yn, char *prefix; /* node-identifier = [prefix ":"] identifier */ char *id; yang_stmt *ys; - yang_stmt *ym2; yang_stmt *yp; cg_var *cv; char *ns; @@ -2586,34 +2597,28 @@ schema_nodeid_iterate(yang_stmt *yn, clicon_err(OE_YANG, EFAULT, "No module for namespace: %s", ns); goto done; } - /* Iterate over children of current node to get a match - * XXX namespace????? - */ - ys = NULL; - while ((ys = yn_each(yp, ys)) != NULL) { - if (!yang_schemanode(ys)) - continue; - - /* some keys dont have arguments, match on key */ - if (ys->ys_keyword == Y_INPUT || ys->ys_keyword == Y_OUTPUT){ - if (strcmp(id, yang_key2str(ys->ys_keyword)) == 0){ - break; - } - } - else { - if (ys->ys_argument && strcmp(id, ys->ys_argument) == 0){ - /* Also check for right prefix/module */ - ym2 = ys->ys_mymodule?ys->ys_mymodule:ys_module(ys); - if (ym2 == ymod) - break; - } - } - } /* while ys */ + ys = yang_find_schemanode(yp, id); + /* Special case: if rpc/action, an empty input/output may need to be created, it is optional but may + * still be referenced. + * XXX: maybe input/output should always be created when rpc/action is created? + */ + if (ys == NULL && + (yang_keyword_get(yp) == Y_RPC || yang_keyword_get(yp) == Y_ACTION) && + (strcmp(id, "input") == 0 || strcmp(id, "output") == 0)){ + enum rfc_6020 kw; + kw = clicon_str2int(ykmap, id); + /* Add ys as id to yp */ + if ((ys = ys_new(kw)) == NULL) + goto done; + if (yn_insert(yp, ys) < 0) /* Insert into hierarchy */ + goto done; + } if (ys == NULL){ clicon_debug(1, "%s: %s not found", __FUNCTION__, id); goto ok; } - yp = ys; + yp = ys; /* ys is matched */ + } /* while cv */ assert(yp && yang_schemanode((yang_stmt*)yp)); *yres = (yang_stmt*)yp; diff --git a/lib/src/clixon_yang_parse.y b/lib/src/clixon_yang_parse.y index f1d09def..f0dd49a3 100644 --- a/lib/src/clixon_yang_parse.y +++ b/lib/src/clixon_yang_parse.y @@ -1791,7 +1791,7 @@ desc_schema_nodeid_str : desc_schema_nodeid desc_schema_nodeid : node_identifier { $$= $1; clicon_debug(3,"descendant-schema-nodeid -> node_identifier"); } | node_identifier abs_schema_nodeid - { if (($$=string_del_join($1, " ", $2)) == NULL) _YYERROR("desc_schema_nodeid");clicon_debug(3,"descendant-schema-nodeid -> node_identifier abs_schema_nodeid"); } + { if (($$=string_del_join($1, "", $2)) == NULL) _YYERROR("desc_schema_nodeid");clicon_debug(3,"descendant-schema-nodeid -> node_identifier abs_schema_nodeid"); } ; identifier_str : '"' IDENTIFIER '"' { $$ = $2; diff --git a/lib/src/clixon_yang_parse_lib.c b/lib/src/clixon_yang_parse_lib.c index 3629c81e..a37e4dbd 100644 --- a/lib/src/clixon_yang_parse_lib.c +++ b/lib/src/clixon_yang_parse_lib.c @@ -238,12 +238,18 @@ yang_augment_node(yang_stmt *ys) goto done; if (ytarget == NULL){ -#if 0 /* Lots of yang models fail here */ +#if 1 + /* Fail with fatal error if augment target not found + * This is "correct" + */ clicon_err(OE_YANG, 0, "Augment failed in module %s: target node %s not found", yang_argument_get(ys_module(ys)), schema_nodeid); goto done; #else + /* Log a warning and proceed if augment target not found + * This may be necessary with some broken models + */ clicon_log(LOG_WARNING, "Warning: Augment failed in module %s: target node %s not found", yang_argument_get(ys_module(ys)), schema_nodeid); @@ -276,7 +282,7 @@ yang_augment_node(yang_stmt *ys) if (childkey != Y_ACTION && childkey != Y_NOTIFICATION && childkey != Y_UNKNOWN && childkey != Y_CONTAINER && childkey != Y_LEAF && childkey != Y_LIST && childkey != Y_LEAF_LIST && childkey != Y_USES && childkey != Y_CHOICE){ - clicon_log(LOG_WARNING, "Warning: A Augment failed in module %s: node %s %d cannot be added to target node %s", + clicon_log(LOG_WARNING, "Warning: Augment failed in module %s: node %s %d cannot be added to target node %s", yang_argument_get(ys_module(ys)), yang_key2str(childkey), childkey, @@ -295,7 +301,7 @@ yang_augment_node(yang_stmt *ys) if (childkey != Y_CONTAINER && childkey != Y_LEAF && childkey != Y_LIST && childkey != Y_LEAF_LIST && childkey != Y_USES && childkey != Y_CHOICE && childkey != Y_UNKNOWN){ - clicon_log(LOG_WARNING, "Warning: B Augment failed in module %s: node %s %d cannot be added to target node %s", + clicon_log(LOG_WARNING, "Warning: Augment failed in module %s: node %s %d cannot be added to target node %s", yang_argument_get(ys_module(ys)), yang_key2str(childkey), childkey, @@ -316,7 +322,7 @@ yang_augment_node(yang_stmt *ys) childkey != Y_CHOICE && childkey != Y_CONTAINER && childkey != Y_LEAF && childkey != Y_LIST && childkey != Y_LEAF_LIST){ - clicon_log(LOG_WARNING, "Warning: C Augment failed in module %s: node %s %d cannot be added to target node %s", + clicon_log(LOG_WARNING, "Warning: Augment failed in module %s: node %s %d cannot be added to target node %s", yang_argument_get(ys_module(ys)), yang_key2str(childkey), childkey, diff --git a/test/test_api.sh b/test/test_api.sh index 92d90612..a0a53dea 100755 --- a/test/test_api.sh +++ b/test/test_api.sh @@ -259,19 +259,17 @@ if [ $RC -ne 0 ]; then stop_restconf fi -if [ $BE -eq 0 ]; then - exit # BE +if [ $BE -ne 0 ]; then + new "Kill backend" + # Check if premature kill + pid=`pgrep -u root -f clixon_backend` + if [ -z "$pid" ]; then + err "backend already dead" + fi + # kill backend + stop_backend -f $cfg fi -new "Kill backend" -# Check if premature kill -pid=`pgrep -u root -f clixon_backend` -if [ -z "$pid" ]; then - err "backend already dead" -fi -# kill backend -stop_backend -f $cfg - # unset conditional parameters unset format diff --git a/test/test_augment.sh b/test/test_augment.sh index 2b0d2909..2f5adb7b 100755 --- a/test/test_augment.sh +++ b/test/test_augment.sh @@ -85,6 +85,20 @@ module ietf-interfaces { type uint16; } } + /* Original choice that gets augmented */ + choice target { + case stream { + leaf one{ + type string; + } + } + } + notification started { + leaf id{ + type string; + } + } + } EOF @@ -145,6 +159,9 @@ module example-augment { refine port { default 80; } + refine ip { + description "double refine triggered mem error"; + } } uses localgroup { description "Use a local grouping defining lip and lport"; @@ -153,7 +170,22 @@ module example-augment { } } } + /* augment choice */ + augment "/if:target" { + case datastore { + leaf two{ + type uint32; + } + } + } + /* augment notification */ + augment "/if:started" { + leaf argument{ + type string; + } + } } + EOF new "test params: -f $cfg" diff --git a/test/test_submodule.sh b/test/test_submodule.sh index 46fd88b0..fd2e0969 100755 --- a/test/test_submodule.sh +++ b/test/test_submodule.sh @@ -66,6 +66,12 @@ module main{ type string; } } + /* Augment something in sub module */ + augment /ex:sub2 { + leaf aug0{ + type string; + } + } } EOF @@ -87,6 +93,18 @@ submodule sub1 { type string; } } + /* Augment something in module */ + augment /ex:main { + leaf aug1{ + type string; + } + } + /* Augment something in another submodule */ + augment /ex:sub2 { + leaf aug2{ + type string; + } + } } EOF @@ -221,6 +239,15 @@ expectpart "$(curl $CURLOPTS -X POST -H "Content-Type: application/yang-data+jso new "restconf check main/sub1/sub2 contents" expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/data?content=config)" 0 'HTTP/1.1 200 OK' '{"data":{"main:main":{"ext":"foo","x":"foo"},"main:sub1":{"ext1":"foo","x":"foo"},"main:sub2":{"ext2":"foo","x":"foo"}' +new "restconf edit augment 0" +expectpart "$(curl $CURLOPTS -X POST -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data/main:sub2 -d '{"main:aug0":"foo"}')" 0 'HTTP/1.1 201 Created' + +new "restconf edit augment 1" +expectpart "$(curl $CURLOPTS -X POST -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data/main:main -d '{"main:aug1":"foo"}')" 0 'HTTP/1.1 201 Created' + +new "restconf edit augment 2" +expectpart "$(curl $CURLOPTS -X POST -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data/main:sub2 -d '{"main:aug2":"foo"}')" 0 'HTTP/1.1 201 Created' + if [ $RC -ne 0 ]; then new "Kill restconf daemon" stop_restconf diff --git a/test/test_yang_models.sh b/test/test_yang_models_ieee.sh similarity index 51% rename from test/test_yang_models.sh rename to test/test_yang_models_ieee.sh index 839214ec..11533479 100755 --- a/test/test_yang_models.sh +++ b/test/test_yang_models_ieee.sh @@ -1,20 +1,10 @@ #!/usr/bin/env bash -# Parse yangmodels from https://github.com/YangModels/yang +# Parse "all" IEEE yangmodels from https://github.com/YangModels/yang/standard/ietf/RFC # Notes: +# - Only a simple smoketest (CLI check) is made, A full system may not work # - Env variable YANGMODELS should point to checkout place. (define it in site.sh for example) -# - Only cisco/nx/9.2-2 # Many other versions -# - Only cisco/xe/1631 # Many other versions -# - Only cisco/xr/530 # Many other versions -# - Only juniper/18.2/18.2R/junos # Many other versions and platoforms - -# These are the test scripts: -#./experimental/ieee/check.sh -#./standard/ieee/check.sh -#./standard/ietf/check.sh -#./vendor/cisco/xr/check.sh -#./vendor/cisco/check.sh -#./vendor/cisco/xe/check.sh -#./vendor/cisco/nx/check.sh +# - Some FEATURES are set to make it work +# - Some DIFFs are necessary in yangmodels (see end of script) # Magic line must be first in script (see README.md) s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi @@ -35,27 +25,24 @@ cat < $cfg $cfg ni-ieee1588-ptp:cmlds - ietf-alarms:alarm-shelving + /usr/local/share/clixon $YANGMODELS/standard/ietf/RFC $YANGMODELS/standard/ieee/draft/802.1/Qcr $YANGMODELS/standard/ieee/draft/802 - $YANGMODELS/standard/ieee/draft/802 $YANGMODELS/standard/ieee/published/802.1 $YANGMODELS/standard/ieee/published/802 - /usr/local/share/clixon - false /usr/local/lib/$APPNAME/clispec /usr/local/lib/$APPNAME/cli $APPNAME /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile /usr/local/var/$APPNAME - true EOF new "yangmodels parse: -f $cfg" + new "yangmodel Experimental IEEE 802.1: $YANGMODELS/experimental/ieee/802.1" expectpart "$($clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/experimental/ieee/802.1 -p $YANGMODELS/experimental/ieee/1588 show version)" 0 "$version." @@ -85,56 +72,22 @@ expectpart "$($clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/s new "yangmodel Standard IEEE 802.1: $YANGMODELS/standard/ieee/published/802.3" expectpart "$($clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/standard/ieee/published/802.3 show version)" 0 "$version." -# Standard IETF -# XXX fails on augmenting "action" -new "yangmodel Standard IETF: $YANGMODELS/standard/ietf/RFC" -expectpart "$($clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/standard/ietf/RFC show version)" 0 "$version." - -# vendor/junos -#junos : M/MX, T/TX, Some EX platforms, ACX -#junos-es : SRX, Jseries, LN-* -#junos-ex : EX series -#junos-qfx : QFX series -#junos-nfx : NFX series - -# Juniper JunOS. Junos files have 4 lines copyright, then "module" on -# line 5. No sub-modules. -# NOTE: We DISABLE CLI generation, because some juniper are very large. -# and cli generation consumes memory. -# For example (100K lines): -#wc /usr/local/share/yangmodels/vendor/juniper/18.2/18.2R1/junos/conf/junos-conf-system@2018-01-01.yang -# 92853 274279 3228229 /usr/local/share/yangmodels/vendor/juniper/18.2/18.2R1/junos/conf/junos-conf-system@2018-01-01.yan -# But junos-conf-logical-systems@2018-01-01.yang takes longest time - -files=$(find $YANGMODELS/vendor/juniper/18.2/18.2R1/junos/conf -name "*.yang") -let i=0; -for f in $files; do - if [ -n "$(head -5 $f|grep '^ module')" ]; then - new "$clixon_cli -1f $cfg -o CLICON_YANG_MAIN_FILE=$f -p $YANGMODELS/vendor/juniper/18.2/18.2R1/common -p $YANGMODELS/vendor/juniper/18.2/18.2R1/junos/conf show version" - expectpart "$($clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_FILE=$f -p $YANGMODELS/vendor/juniper/18.2/18.2R1/common -p $YANGMODELS/vendor/juniper/18.2/18.2R1/junos/conf -o CLICON_CLI_GENMODEL=0 show version)" 0 "$version." - let i++; - sleep 1 - fi -done - -# We skip CISCO because we have errors that vilates the RFC (I think) -# eg: Test 7(7) [yangmodel vendor cisco xr 623: /usr/local/share/yangmodels/vendor/cisco/xr/623] -# yang_abs_schema_nodeid: Absolute schema nodeid /bgp-rib/afi-safis/afi-safi/ipv4-unicast/loc-rib must have prefix - -if false; then -# vendor/cisco/xr -new "yangmodel vendor cisco xr 623: $YANGMODELS/vendor/cisco/xr/623" -expectpart "$($clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/vendor/cisco/xr/623 show version)" 0 "$version." - -new "yangmodel vendor cisco xr 632: $YANGMODELS/vendor/cisco/xr/632" -expectpart "$($clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/vendor/cisco/xr/632 show version)" 0 "$version." - -new "yangmodel vendor cisco xr 623: $YANGMODELS/vendor/cisco/xr/642" -expectpart "$($clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/vendor/cisco/xr/642 show version)" 0 "$version." - -new "yangmodel vendor cisco xr 651: $YANGMODELS/vendor/cisco/xr/651" -expectpart "$($clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/vendor/cisco/xr/651 show version)" 0 "$version." -fi ### cisco - rm -rf $dir +exit 0 + +# Diff to make it work + +diff --git a/standard/ieee/published/802.3/ieee802-ethernet-pon.yang b/standard/ieee/published/802.3/ieee802-ethernet-pon.yang +index 37c54c2a..a56b5f50 100755 +--- a/standard/ieee/published/802.3/ieee802-ethernet-pon.yang ++++ b/standard/ieee/published/802.3/ieee802-ethernet-pon.yang +@@ -2421,7 +2421,7 @@ module ieee802-ethernet-pon { + } + + leaf mpcp-maximum-queue-count-per-report { +- when "../ompe-mode = olt'"; ++ when "../ompe-mode = 'olt'";^M + type mpcp-maximum-queue-count-per-report; + + config false; diff --git a/test/test_yang_models_ietf.sh b/test/test_yang_models_ietf.sh new file mode 100755 index 00000000..81015141 --- /dev/null +++ b/test/test_yang_models_ietf.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# Parse "all" IETF yangmodels from https://github.com/YangModels/yang/standard/ieee and experimental/ieee +# Notes: +# - Only a simple smoketest (CLI check) is made, A full system may not work +# - Env variable YANGMODELS should point to checkout place. (define it in site.sh for example) +# - Some FEATURES are set to make it work +# - Some DIFFs are necessary in yangmodels (see end of script) + +# Magic line must be first in script (see README.md) +s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi + +# Yang specifics: multi-keys and empty type +APPNAME=example + +cfg=$dir/conf_yang.xml +fyang=$dir/test.yang + +YANGMODELS=/home/olof/tmp/yang +if [ ! -d "$YANGMODELS" ]; then +# err "Hmm Yangmodels dir does not seem to exist, try git clone https://github.com/YangModels/yang?" + if [ "$s" = $0 ]; then exit 0; else return 0; fi +fi + +cat < $cfg + + $cfg + ietf-alarms:alarm-shelving + ietf-subscribed-notifications:configured + ietf-subscribed-notifications:replay + ietf-access-control-list:match-on-tcp + /usr/local/share/clixon + $YANGMODELS/standard/ieee/published/802.1 + /usr/local/lib/$APPNAME/clispec + /usr/local/lib/$APPNAME/cli + $APPNAME + /usr/local/var/$APPNAME/$APPNAME.sock + /usr/local/var/$APPNAME/$APPNAME.pidfile + /usr/local/var/$APPNAME + +EOF + +# Standard IETF +new "yangmodel Standard IETF: $YANGMODELS/standard/ietf/RFC" +echo "$clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/standard/ietf/RFC show version" +expectpart "$($clixon_cli -D $DBG -1f $cfg -o CLICON_YANG_MAIN_DIR=$YANGMODELS/standard/ietf/RFC show version)" 0 "$version." + +rm -rf $dir + +exit 0 + +# Diff to make it work + +diff --git a/standard/ietf/RFC/ietf-mud@2019-01-28.yang b/standard/ietf/RFC/ietf-mud@2019-01-28.yang +index 1842284e..4197ad46 100644 +--- a/standard/ietf/RFC/ietf-mud@2019-01-28.yang ++++ b/standard/ietf/RFC/ietf-mud@2019-01-28.yang +@@ -297,7 +297,7 @@ module ietf-mud { + } + } + augment "/acl:acls/acl:acl/acl:aces/acl:ace/acl:matches" +- + "/acl:l4/acl:tcp/acl:tcp" { ++ + "/acl:l4/acl:tcp" { /* Olof: rm extra /acl:tcp */ + description + "add direction-initiated"; + leaf direction-initiated {