Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prefix is empty when handling identityref (libyang 2.1.144) #2146

Open
optimden opened this issue Dec 20, 2023 · 3 comments
Open

Prefix is empty when handling identityref (libyang 2.1.144) #2146

optimden opened this issue Dec 20, 2023 · 3 comments
Labels
is:question Issue is actually a question.

Comments

@optimden
Copy link
Contributor

optimden commented Dec 20, 2023

Hello!
I discovered the following problem on the libyang version 2.1.144.
Other related libs versions:
libnetconf2 - 2.1.38
sysrepo - 2.2.33
netopeer2 - 2.1.49
We sent get-config into the running datastore on the whole yang tree. Saved received config, and then send edit-config with content of this file to the candidate datastore. And got error in a response:

<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:9947300b-a5cf-4add-983d-7f266fdda739">
     <rpc-error>
       <error-type>application</error-type>
       <error-tag>operation-failed</error-tag>
       <error-severity>error</error-severity>
       <error-message xml:lang="en">Invalid identityref "match-all-filter" value - identity not found in module "ietf-netconf". (Data location "/bbf-qos-classifiers:classifiers/classifier-entry[name='initclss-eth0_0-0']/filter-operation".)</error-message>
     </rpc-error>
     <rpc-error>
       <error-type>application</error-type>
       <error-tag>operation-failed</error-tag>
       <error-severity>error</error-severity>
       <error-message xml:lang="en">User callback failed.</error-message>
     </rpc-error>
   </rpc-reply>

I discovered, that we handle identityref in function identityref_str2ident. But problem is that during handling the next part of xml:

<bbf-qos-cls:filter-operation>match-all-filter<bbf-qos-cls:filter-operation>

we got only:

match-all-filter<bbf-qos-cls:filter-operation>

as "value" parameter of identityref_str2ident function. Then we try to parse prefix from value inside it:

for (prefix_len = 0; (prefix_len < value_len) && (value[prefix_len] != ':'); ++prefix_len) {}
if (prefix_len < value_len) {
    id_name = &value[prefix_len + 1];
    id_len = value_len - (prefix_len + 1);
} else {
    prefix_len = 0;
    id_name = value;
    id_len = value_len; 
}

Of course, we can find nothing before we rich value_len and set prefix_len to 0. Then we have the same stacktrace into identityref_str2ident:

lyplg_type_identity_module
    |
ly_xml_resolve_prefix(ctx, NULL, 0, prefix_data)   <--- go here by switch condition

I see, that even if we found prefix, we never try find real matching between it and prefixes, which are stored in prefix_data set. We hardcode NULL as second paramter instead of pass prefix parameter, and 0 instead of real prefix_len.

@michalvasko
Copy link
Member

I do not know exactly where you get the data (it should not be netopeer2)

<bbf-qos-cls:filter-operation>match-all-filter<bbf-qos-cls:filter-operation>

but they are wrong if match-all-filter is from the bbf-qos-cls module. Based on what is said in RFC 7950:

   An identityref is lexically represented as the referred identity's
   qualified name as defined in XML-NAMES.  If the prefix is not
   present, the namespace of the identityref is the default namespace
   in effect on the element that contains the identityref value.

the default namespace is used, not the one of the prefix.

@michalvasko michalvasko added the is:question Issue is actually a question. label Dec 20, 2023
@optimden
Copy link
Contributor Author

I do not know exactly where you get the data (it should not be netopeer2)

<bbf-qos-cls:filter-operation>match-all-filter<bbf-qos-cls:filter-operation>

but they are wrong if match-all-filter is from the bbf-qos-cls module. Based on what is said in RFC 7950:

   An identityref is lexically represented as the referred identity's
   qualified name as defined in XML-NAMES.  If the prefix is not
   present, the namespace of the identityref is the default namespace
   in effect on the element that contains the identityref value.

the default namespace is used, not the one of the prefix.

Well, actually I have problem with applying deviation replace on default value. I have custom yang, which contains such deviation:

deviation "/bbf-qos-cls:classifiers/bbf-qos-cls:classifier-entry/bbf-qos-cls:filter-operation" {
        deviate replace {
            default "bbf-qos-cls:match-all-filter";
        }
    }

I imported modules using custom binary, which use sr_install_modules2 function from sysrepo. All is okey, but as a result i see, that startup datastore file bbf-qos-classifiers.yang in /etc/sysrepo/data/ contains value "match-all-filter" without any prefix. So, the default value for bbf-qos-cls:filter-operation was changed from "match-any-filter". But prefix is absent. And it's the reason of error:

Invalid identityref "match-all-filter" value - identity not found in module "ietf-netconf"

Behaviour on the previous versions of libyang, sysrepo and netopeer was such, that i have match-all-filter in startup datastore with prefix after applying deviation.
I examined, that inside "sr_install_modules2" sysrepo function I go through the following stacktrace:
sr_install_modules2
|
_sr_install_modules
|
sr_lycc_update_data
|
lyd_validate_all <--- validation for a startup datastore
|
lyd_new_implicit_r <--- here I had been stopped by condition that: (struct lysc_node *)iter->name == "filter-operation".
I checked, that i still have here for (struct lysc_node_leaf *)iter->dflt value "bbf-qos-classifiers:math-all-filter". But it seems, that this full name prefix will be removed further before printing this value via libyang to startup datastore file.
Can you please reproduce such scenario and help to investigate the root cause?

@michalvasko
Copy link
Member

That is all fine, the value match-all-filter is correct in XML such as

<filter-operation xmlns="urn:bbf:yang:bbf-qos-classifiers">match-all-filter<filter-operation>

because it simply inherits the default namespace. That is why I have asked (and am asking again) how exactly did you get the XML data that are not using a default namespace but a prefixed namespace instead? Those are the only problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
is:question Issue is actually a question.
Projects
None yet
Development

No branches or pull requests

2 participants