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

Cannot get child using XPATH #414

Open
dima1308 opened this issue Jan 31, 2023 · 9 comments
Open

Cannot get child using XPATH #414

dima1308 opened this issue Jan 31, 2023 · 9 comments
Assignees
Labels

Comments

@dima1308
Copy link

dima1308 commented Jan 31, 2023

When I execute the following query:

<get>
  <filter type="subtree">
    <rb-tg-if:interfaces xmlns:rb-tg-if="http://siklu.com/yang/tg/interfaces"/>
  </filter>
</get>

I get the following response:

<?xml version="1.0" encoding="utf-8"?>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <interfaces xmlns="http://siklu.com/yang/tg/interfaces">
    <host>
      <state>
        <mac-address>00:24:a4:16:51:a1</mac-address>
        <counters>
          <in-octets>157432</in-octets>
          <in-pkts>3730</in-pkts>
          <in-discards>0</in-discards>
          <in-errors>0</in-errors>
          <in-no-rule-discards>4</in-no-rule-discards>
          <out-octets>6791986</out-octets>
          <out-pkts>60877</out-pkts>
          <out-discards>0</out-discards>
          <out-errors>0</out-errors>
        </counters>
      </state>
    </host>
    <ports>
      <name>eth1</name>
      <alias>myeth1</alias>
      <admin-status>up</admin-status>
      <copper-specific-config>
        <auto-negotiate>true</auto-negotiate>
      </copper-specific-config>
      <connector-type>RJ-45</connector-type>
      <port-speed>10Gbps</port-speed>
      <state>
        <oper-status>up</oper-status>
        <actual-duplex-mode>full</actual-duplex-mode>
        <actual-port-speed>1Gbps</actual-port-speed>
        <counters>
          <in-octets>6407339</in-octets>
          <in-pkts>55797</in-pkts>
          <in-discards>0</in-discards>
          <in-errors>0</in-errors>
          <in-no-rule-discards>5</in-no-rule-discards>
          <out-octets>532508</out-octets>
          <out-pkts>8699</out-pkts>
          <out-discards>0</out-discards>
          <out-errors>0</out-errors>
        </counters>
      </state>
    </ports>
    <ports>
      <name>eth2</name>
      <alias>myeth2</alias>
      <admin-status>up</admin-status>
      <copper-specific-config>
        <auto-negotiate>true</auto-negotiate>
        <pse-out>true</pse-out>
      </copper-specific-config>
      <connector-type>RJ-45</connector-type>
      <port-speed>1Gbps</port-speed>
      <state>
        <oper-status>down</oper-status>
        <counters>
          <in-octets>0</in-octets>
          <in-pkts>0</in-pkts>
          <in-discards>0</in-discards>
          <in-errors>0</in-errors>
          <in-no-rule-discards>0</in-no-rule-discards>
          <out-octets>0</out-octets>
          <out-pkts>0</out-pkts>
          <out-discards>0</out-discards>
          <out-errors>0</out-errors>
        </counters>
      </state>
    </ports>
    <ports>
      <name>eth3</name>
      <alias>myeth3</alias>
      <admin-status>up</admin-status>
      <copper-specific-config>
        <auto-negotiate>true</auto-negotiate>
      </copper-specific-config>
      <connector-type>SFP+</connector-type>
      <port-speed>10Gbps</port-speed>
      <state>
        <oper-status>down</oper-status>
        <counters>
          <in-octets>0</in-octets>
          <in-pkts>0</in-pkts>
          <in-discards>0</in-discards>
          <in-errors>0</in-errors>
          <in-no-rule-discards>0</in-no-rule-discards>
          <out-octets>0</out-octets>
          <out-pkts>0</out-pkts>
          <out-discards>0</out-discards>
          <out-errors>0</out-errors>
        </counters>
      </state>
    </ports>
    <rf-interface>
      <name>rf-23654789</name>
      <state>
        <oper-status>up</oper-status>
        <counters>
          <in-octets>22536898</in-octets>
          <in-pkts>33518</in-pkts>
          <in-discards>0</in-discards>
          <in-errors>0</in-errors>
          <in-no-rule-discards>0</in-no-rule-discards>
          <out-octets>4706450</out-octets>
          <out-pkts>31432</out-pkts>
          <out-discards>0</out-discards>
          <out-errors>0</out-errors>
        </counters>
      </state>
    </rf-interface>
    <tunnels>
      <name>tunnel-1</name>
      <oper-status>unknown</oper-status>
      <counters>
        <in-octets>0</in-octets>
        <in-pkts>0</in-pkts>
        <in-discards>0</in-discards>
        <in-errors>0</in-errors>
        <in-no-rule-discards>0</in-no-rule-discards>
        <out-octets>0</out-octets>
        <out-pkts>0</out-pkts>
        <out-discards>0</out-discards>
        <out-errors>0</out-errors>
      </counters>
    </tunnels>
  </interfaces>
</data>

Now, I'm only trying to get a list of interface names using the following query:

<get>
  <filter xmlns:rb-tg-if="http://siklu.com/yang/tg/interfaces" type="xpath"
          select="/rb-tg-if:interfaces/rb-tg-if:ports/rb-tg-if:name"/>
</get>

I got the expected result:

<?xml version="1.0" encoding="utf-8"?>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <interfaces xmlns="http://siklu.com/yang/tg/interfaces">
    <ports>
      <name>eth1</name>
    </ports>
    <ports>
      <name>eth2</name>
    </ports>
    <ports>
      <name>eth3</name>
    </ports>
  </interfaces>
</data>

Next, I am trying to get interfaces with alias='myeth2':

<get>
  <filter xmlns:rb-tg-if="http://siklu.com/yang/tg/interfaces" type="xpath"
          select="/rb-tg-if:interfaces/rb-tg-if:ports[rb-tg-if:alias='myeth2']"/>
</get>

I received the following result, as expected (we have one interface matching the condition):

<?xml version="1.0" encoding="utf-8"?>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <interfaces xmlns="http://siklu.com/yang/tg/interfaces">
    <ports>
      <name>eth2</name>
      <alias>myeth2</alias>
      <admin-status>up</admin-status>
      <copper-specific-config>
        <auto-negotiate>true</auto-negotiate>
        <pse-out>true</pse-out>
      </copper-specific-config>
      <connector-type>RJ-45</connector-type>
      <port-speed>1Gbps</port-speed>
      <state>
        <oper-status>down</oper-status>
        <counters>
          <in-octets>0</in-octets>
          <in-pkts>0</in-pkts>
          <in-discards>0</in-discards>
          <in-errors>0</in-errors>
          <in-no-rule-discards>0</in-no-rule-discards>
          <out-octets>0</out-octets>
          <out-pkts>0</out-pkts>
          <out-discards>0</out-discards>
          <out-errors>0</out-errors>
        </counters>
      </state>
    </ports>
  </interfaces>
</data>

And now, I'm trying to get only the name of the interface matching the same condition as above:

<get>
  <filter xmlns:rb-tg-if="http://siklu.com/yang/tg/interfaces" type="xpath"
          select="/rb-tg-if:interfaces/rb-tg-if:ports[rb-tg-if:alias='myeth2']/rb-tg-if:name"/>
</get>

I got an empty response - which is not expected since the previous query returns one record matching the condition:

<?xml version="1.0" encoding="utf-8"?>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/>

if I change the query as shown below, I got both values: name and alias in the response:
The request:

<get>
  <filter xmlns:rb-tg-if="http://siklu.com/yang/tg/interfaces" type="xpath"
          select="/rb-tg-if:interfaces/rb-tg-if:ports[rb-tg-if:alias='myeth2']/rb-tg-if:alias"/>
</get>

The response:

<?xml version="1.0" encoding="utf-8"?>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <interfaces xmlns="http://siklu.com/yang/tg/interfaces">
    <ports>
      <name>eth2</name>
      <alias>myeth2</alias>
    </ports>
  </interfaces>
</data>

In this case, I expect to get output that will only include alias

We use CLIXON from Jan 20, 2023, hash: b3dcee9

To summarize, I saw two issues:

  1. In some cases, an empty response for the request
  2. Not expected value in the response.

Please see attached yang models we use: yang.zip

@olofhagsand
Copy link
Member

I have recreated the problem.
The XPATH function works, but is broken with the NETCONF filter handling.

@olofhagsand
Copy link
Member

The two cases above:

  1. In some cases, an empty response for the request
  2. Not expected value in the response.

The two cases are quite different, where (1) is in fact a bug, while (2) follows RFC6241

Issue (1) is a larger issue that requires some restructuring of the xmldb code + default values and is not an easy fix.
It is a necessary refactoring that has been planned for some time.
In short, it has to do with how the function works:

  1. Get the requested config without default values and apply xpath.
  2. Add default values according to with-defaults setting
  3. Add state data
  4. Make a new xpath (to filter default and state data).
    The problem is that xpath is made in two steps (1 and 4). Information relevant to the xpath may therefore be removed in step 1 and is not relevant in step 4. This explains issue : "In some cases, an empty response for the request".
    This is a bug.

Issue (2), RFC 6241 Section 8.9.1 says:

The response message contains the subtrees selected by the filter
expression. For each such subtree, the path from the data model root
node down to the subtree, including any elements or attributes
necessary to uniquely identify the subtree, are included in the
response message. Specific data instances are not duplicated in the
response.

which clixon interprets as YANG keys must be included "to identify the subtree".
A client could make an xpath call (ie clixon_snmp) after the the call to make a proper XPATH filtering where the key nodes will be removed.
Therefore this is not considered a bug.

olofhagsand added a commit that referenced this issue Feb 2, 2023
New tests and help texts
@dima1308
Copy link
Author

@olofhagsand may I ask you what is the status of the fix for this?

@olofhagsand
Copy link
Member

The refactoring necessary for this was initially planned for 6.2, but has now been pushed to 6.3. Refactoring of netconf input code was made before.

@dima1308
Copy link
Author

@olofhagsand Can I inquire about the status of the fix? It was scheduled for 6.3, but from what I can observe, it was not incorporated into the release.

@olofhagsand
Copy link
Member

olofhagsand commented Jul 30, 2023 via email

@dima1308
Copy link
Author

This bug prevents us from merging #415.
I guess, we can merge it now since this bug is fixed. Correct?

@shmuelhazan
Copy link
Contributor

@dima1308 @olofhagsand Looks like this bug has not been fixed (#415 fails still, due to this bug)

@olofhagsand
Copy link
Member

@dima1308 @shmuelhazan . On closer inspection, this refers to a refactoring that has not been made yet. Thus issue (1) above still remains and is not fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants