-
Notifications
You must be signed in to change notification settings - Fork 35
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
Example for custom generic netlink family with custom attributes #103
Conversation
Of course this will not build/terminate in any CI system because the kernel module doesn't exist there. But it will fail, not stuck in a loop or so. |
sock.recv().expect("Should receive a message").unwrap(); | ||
|
||
// According to Netlink Linux kernel code nl_type is either 0x2 (error) or our family id (ok) | ||
if res.nl_type == 0x2 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I have to refactor this. Looks like this check is already covered by sock.recv(). It returns Err if nl_type is 0x2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, neli tells The buffer was not large enough to complete the deserialize operation
. Doesn't look what I would neli expect to do. Technically an "well formed error message" is okay but not error
Probably found a general neli problem that is not related to this specific PR. I just want to note it here: Netlinks man page also encourages developers to use NLMSG_ERR to signalize error. |
@phip1611 Thanks for the report! So just to confirm, you returned an error packet with no
from here. Unless you can give me a specific link to documentation that specifies that this payload is optional, I think this is a problem in your implementation, not in mine. |
I am happy to create an issue to improve error messaging if that would be helpful for you. I've also bumped into some situations where the error messaging is not adequate and I'd like to improve the error provided to the user in certain cases. |
@jbaublitz You are right. I'm not a netlink expert and I just tried to use it in a way that it works for me. My Kernel module didn't include But can you imagine a more convenient way to recognize the absence of this struct, when PS: I update my kernel module to include the struct in the payload in error case. I edit this comment when I have an update on this. |
Perfect! I'll open an issue and tag you in it so we can discuss details. |
I have a few comments on the code so far. I'll review this soon and request some changes just so that people looking at the code are guided towards neli best practices when they look at the example. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here are some initial notes.
use neli::consts::nl::Nlmsg; | ||
use neli::consts::nl::{NlmF, NlmFFlags}; | ||
use neli::consts::socket::NlFamily; | ||
use neli::genl::{Genlmsghdr, Nlattr}; | ||
use neli::nl::{NlPayload, Nlmsghdr}; | ||
use neli::socket::NlSocketHandle; | ||
use neli::types::{Buffer, GenlBuffer}; | ||
use neli::utils::U32Bitmask; | ||
use neli::Nl; | ||
use std::process; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you switch this to nested imports? I've been meaning to put out some formal coding style guidelines but haven't gotten around to that quite yet.
sock.recv().expect("Should receive a message").unwrap(); | ||
|
||
// According to Netlink Linux kernel code nl_type is either 0x2 (error) or our family id (ok) | ||
if res.nl_type == u16::from(Nlmsg::Error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
neli has special handling for the Nlmsg::Error
value as of 0.5.0. This value indicates either an actual error if the error code is non-zero or an ACK if the error code is 0. neli will return these as values of either NlPayload::Ack
or NlPayload::Err
in the resulting Nlmsghdr
. In the error case, recv()
will detect this as an error and return it as an Err(Nlmsgerr)
value. Can you explain a little bit more why you chose to do the checking manually here? Does this use case not work for you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, apparently I was using the neli lib wrong in my uni project and therefore also in this demo.
I didn't had a proper example at the first place that fit my use case, therefore I just tried to figure everything out by myself. I'll improve the code and let you know if it works better. @jbaublitz
let received = attr_handle.get_attribute(FoobarAttribute::Msg).unwrap(); | ||
let received = String::deserialize(received.nla_payload.as_ref()).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be more concisely represented by attr_handle.get_attr_payload_as::<String>(FoobarAttribute::Msg)
.
@jbaublitz FYI I'll fix this in the next weeks, I didn't forget it. I'm having a deadline for an uni project this sunday (where I use neli :)) |
@jbaublitz Sorry it took a while, I updated the PR. Any more comments on the code? Of course I tested it and it's working. PS: I don't get why this fails: https://github.com/jbaublitz/neli/pull/103/checks?check_run_id=1871771582 |
I just reran the failed test and realized that this is a new clippy error in my code. I'll fix that. |
@phip1611 Clippy checks are now optional in CI. If you rebase onto master, you should be good to go. |
@jbaublitz done; pushed the rebased branch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once this last change is made, I'll merge this. Thanks for putting so much effort into the documentation!
@jbaublitz I fixed it. |
I'd like to add an example on how to use neli with custom properties for custom generic netlink families. I use this at an uni project where I develop a kernel module (which registers a custom generic netlink family), a userland component in Rust (using neli), and a other userland component using libnl. Therefore I can ensure that my approach works with the kernel / other netlink implementations.
Let's assume we have a custom kernel driver that registers a
"your_family_name_here"
family. The subject of our problem knows the operations/commandsecho
,create device
, anddelete device
. It also knows the attributesmsg (string)
anddevice name (string)
.In this example (see code) an
echo
message is send to the kernel and the reply received:PS: Example kernel module that fulfills this contract: https://github.com/phip1611/generic-netlink-user-kernel-rust
PPS: When I started doing this project (with neli 0.4.3) I spend so much time on this. Therefore I'd love to have an easy example in this great lib so that others can profit.
Let me know what you think :)