YANG deviation: Resolve deviated types lexically in deviation context

This commit is contained in:
Olof hagsand 2024-08-16 13:32:00 +02:00
parent 1709537701
commit b1a4656f72
4 changed files with 84 additions and 6 deletions

View file

@ -49,6 +49,7 @@ Developers may need to change their code
### Corrected Busg ### Corrected Busg
* Fixed: Deviated types were resolved in target context, not lexically in deviation context
* Fixed: Signal handling of recv message * Fixed: Signal handling of recv message
Revert to signal handling in 6.5 that was changed in the netconf uniform handling in 7.0 Revert to signal handling in 6.5 that was changed in the netconf uniform handling in 7.0
* Fixed: [NETCONF error reply from failed leafref rquire-instance does not comply to RFC 7950](https://github.com/clicon/clixon/issues/536) * Fixed: [NETCONF error reply from failed leafref rquire-instance does not comply to RFC 7950](https://github.com/clicon/clixon/issues/536)

View file

@ -2416,6 +2416,14 @@ yang_deviation(yang_stmt *ys,
/* Make a copy of deviate child and insert. */ /* Make a copy of deviate child and insert. */
if ((yc1 = ys_dup(yc)) == NULL) if ((yc1 = ys_dup(yc)) == NULL)
goto done; goto done;
/* Special case: resolve types in temporary old deviation context */
if (yn_insert(yd, yc1) < 0)
goto done;
if (yang_apply(yc1, Y_TYPE, ys_resolve_type, -1, h) < 0)
goto done;
if (ys_prune_self(yc1) < 0)
goto done;
/* Mark all as refined */
if (yang_apply(yc1, -1, (yang_applyfn_t*)yang_flag_set, -1, (void*)YANG_FLAG_REFINE) < 0) if (yang_apply(yc1, -1, (yang_applyfn_t*)yang_flag_set, -1, (void*)YANG_FLAG_REFINE) < 0)
goto done; goto done;
if (yn_insert(ytarget, yc1) < 0) if (yn_insert(ytarget, yc1) < 0)
@ -2451,6 +2459,14 @@ yang_deviation(yang_stmt *ys,
/* Make a copy of deviate child and insert. */ /* Make a copy of deviate child and insert. */
if ((yc1 = ys_dup(yc)) == NULL) if ((yc1 = ys_dup(yc)) == NULL)
goto done; goto done;
/* Special case: resolve types in temporary old deviation context */
if (yn_insert(yd, yc1) < 0)
goto done;
if (yang_apply(yc1, Y_TYPE, ys_resolve_type, -1, h) < 0)
goto done;
if (ys_prune_self(yc1) < 0)
goto done;
/* Mark all as refined */
if (yang_apply(yc1, -1, (yang_applyfn_t*)yang_flag_set, -1, (void*)YANG_FLAG_REFINE) < 0) if (yang_apply(yc1, -1, (yang_applyfn_t*)yang_flag_set, -1, (void*)YANG_FLAG_REFINE) < 0)
goto done; goto done;
if (yn_insert(ytarget, yc1) < 0) if (yn_insert(ytarget, yc1) < 0)

View file

@ -256,11 +256,16 @@ ys_resolve_type(yang_stmt *ytype,
uint8_t fraction = 0; uint8_t fraction = 0;
yang_stmt *resolved = NULL; yang_stmt *resolved = NULL;
cvec *regexps = NULL; cvec *regexps = NULL;
yang_stmt *yp;
if (yang_keyword_get(ytype) != Y_TYPE){ if (yang_keyword_get(ytype) != Y_TYPE){
clixon_err(OE_YANG, EINVAL, "Expected Y_TYPE"); clixon_err(OE_YANG, EINVAL, "Expected Y_TYPE");
goto done; goto done;
} }
if ((yp = yang_parent_get(ytype)) == NULL){
clixon_err(OE_YANG, EINVAL, "ytype has no parent");
goto done;
}
if ((patterns = cvec_new(0)) == NULL){ if ((patterns = cvec_new(0)) == NULL){
clixon_err(OE_UNIX, errno, "cvec_new"); clixon_err(OE_UNIX, errno, "cvec_new");
goto done; goto done;
@ -268,8 +273,7 @@ ys_resolve_type(yang_stmt *ytype,
/* Recursively resolve ytype -> resolve with restrictions(options, etc) /* Recursively resolve ytype -> resolve with restrictions(options, etc)
* Note that the resolved type could be ytype itself. * Note that the resolved type could be ytype itself.
*/ */
if (yang_type_resolve(yang_parent_get(ytype), yang_parent_get(ytype), if (yang_type_resolve(yp, yp, ytype, &resolved,
ytype, &resolved,
&options, &cvv, patterns, NULL, &fraction) < 0){ &options, &cvv, patterns, NULL, &fraction) < 0){
goto done; goto done;
} }

View file

@ -230,7 +230,7 @@ testrun true false true false
cat <<EOF > $fyangdev cat <<EOF > $fyangdev
module example-deviations{ module example-deviations{
yang-version 1.1; yang-version 1.1;
prefix md; prefix ed;
namespace "urn:example:deviations"; namespace "urn:example:deviations";
import example-base { import example-base {
prefix base; prefix base;
@ -246,7 +246,9 @@ EOF
new "5. deviate delete" new "5. deviate delete"
testrun true false false true testrun true false false true
# Replace example from RFC 7950 Sec 7.20.3.3 # Here follows advanced deviations (from arista/openconfig deviations)
new "6. deviate replace default"
cat <<EOF > $fyangdev cat <<EOF > $fyangdev
module example-deviations{ module example-deviations{
yang-version 1.1; yang-version 1.1;
@ -268,8 +270,6 @@ module example-deviations{
} }
EOF EOF
new "6. deviate replace default"
if [ "$BE" -ne 0 ]; then if [ "$BE" -ne 0 ]; then
new "kill old backend" new "kill old backend"
sudo clixon_backend -zf "$cfg" sudo clixon_backend -zf "$cfg"
@ -309,6 +309,63 @@ if [ "$BE" -ne 0 ]; then
stop_backend -f "$cfg" stop_backend -f "$cfg"
fi fi
# lexically scoped
new "7. deviate with own type"
cat <<EOF > $fyangdev
module example-deviations{
yang-version 1.1;
prefix ed;
namespace "urn:example:deviations";
import example-base {
prefix base;
}
typedef mytype {
type int8;
}
deviation /base:system/base:my {
deviate replace {
type ed:mytype;
}
}
}
EOF
if [ "$BE" -ne 0 ]; then
new "kill old backend"
sudo clixon_backend -zf "$cfg"
if [ $? -ne 0 ]; then
err
fi
new "start backend -s init -f $cfg"
start_backend -s init -f "$cfg"
fi
new "wait backend"
wait_backend
new "set negative value"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:base\"><daytime>Sept17</daytime><my>-77</my></system></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
new "netconf validate ok"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
new "set large value"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:base\"><my>98735</my></system></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
new "netconf validate expect fail"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>my</bad-element></error-info><error-severity>error</error-severity><error-message>Number 98735 out of range: -128 - 127</error-message></rpc-error></rpc-reply>"
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
rm -rf "$dir" rm -rf "$dir"
new "endtest" new "endtest"