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

Question: Usage of NLA_SLOT objects #670

Open
Vic063 opened this issue Feb 7, 2020 · 5 comments
Open

Question: Usage of NLA_SLOT objects #670

Vic063 opened this issue Feb 7, 2020 · 5 comments
Labels

Comments

@Vic063
Copy link
Contributor

Vic063 commented Feb 7, 2020

Hello,

I'm trying to implement a new ematch decoder which uses different types of values depending on the selected ematch kind.

The value can either be a string value or an uint32_t value.
As a workaroud, I set the value type to 'hex' in the nla_map so I can manipulate the hex data as I want to decode it as an integer or a string.

However, when I want to replace the original hex value with the one just decoded, I thought it was a tuple object but it's a nla_slot object (and the nldecap decoder does not print the tree correctly).

As an essay, I tried to directly create a nla_slot but it fails. I looked at the code (class nla_slot in pyroute2/netlink/init.py) but it seems there is no way to edit/replace the value of a nla_slot.

Do you think it can be acceptable to add a 'set_value' method to override nla_slot value?
Or is there a way to do it without any modification in the pyroute2 engine?

Thank you.

@svinota
Copy link
Owner

svinota commented Feb 7, 2020

As a generic solution you can do this way:

from pyroute2.netlink import nla

class some_normal_msg(nlmsg):
    nla_map = (('NORMAL_UNSPEC', 'none'),
               ('NORMAL_EXAMPLE_UINT32', 'uint32'),
               ('NORMAL_EXAMPLE_CUSTOM', 'my_nla'))

    class my_nla(nla):
        # the parser interacts with self.fields, in this case it will be self['value']
        fields = [('value', 's')]
        # in the case of a simple nla with the only value the user will get/set
        # the self.value attribute implicitly, see also encode()/decode() below

        def decode(self):
            # first run generic decode into a string data
            nla.decode(self)
            # now the data is saved into self['value'], manipulate it
            # self.value will be returned as a simple value of the nla
            self.value = my_transform_out(self['value'])

        def encode(self):
            # the assigned value is stored in self.value, transform it
            self['value'] = my_transform_in(self.value)
            # now run the generic encoding
            nla.encode(self)

The API is a bit weird and badly needs redesign, but by historical reasons it's like that right now.

The nla_slot is a proxy object that has only one goal: it defers nla decoding until it will be referenced directly. Thus not referenced data doesn't get decoded, saving some CPU resources.

@svinota svinota added the docs label Feb 7, 2020
@svinota
Copy link
Owner

svinota commented Feb 7, 2020

Or maybe I got your question wrong. Then ping me pls.

@Vic063
Copy link
Contributor Author

Vic063 commented Feb 7, 2020

Thank you for your answer. You can look at PR #671 to see exactly what I'm talking about (from lines 87 to 96) :)

I wanted to try your advice however it breaks the netlink packet structure.

@svinota
Copy link
Owner

svinota commented Feb 7, 2020

Ok, let me play a bit with the code.

@svinota
Copy link
Owner

svinota commented Feb 7, 2020

from lines 87 to 96

Yep, I've got it. I believe we can solve this.

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

2 participants