-
Notifications
You must be signed in to change notification settings - Fork 72
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
Netlink (neli) code for the CAN interfaces #32
Comments
Personally, I have never used it directly. Of course, I have used iptools to create and manipulate CAN interfaces, but never used the netlink API directly. Would be willing to investigate though, given some free time. Just can't give any authorative answers. The (only) must-have use cases based on my work:
Reading through the socketcan docs once again, it does support quite a lot of stuff which would certainly be useful, though. |
Thanks, @jreppnow . Setting the baud rate and secondary (FD) baud rate would be a great next step. The code to bring the interface up and down is in there, and to my knowledge works. It's probably a good example to get started on the rest. If you were to get started on it, let us know, so that the work is not duplicated. |
I'll have some time to look at this in detail over the next weekend, although I'll presumably have to do quite a bit of research first. If that's fine in terms of delay, I'd gladly take a swing. |
Sounds like a plan. Over the weekend I will get back to looking at timestamps. |
So I started working on the bitrate stuff in order to use it as an example for a guide, but it's pretty hairy tbh. The main issue is that a lot of constants and structs are missing and it's overall very fiddly. You can see my current progress here: https://github.com/jreppnow/socketcan-rs/tree/netlink-bitrate I still going to go ahead and describe my basic approach so that others can follow through. Recommended reading: https://man7.org/linux/man-pages/man7/netlink.7.html and specifically https://man7.org/linux/man-pages/man7/rtnetlink.7.html. For cross-referencing, I recommend looking at the iproute2 source code at https://github.com/shemminger/iproute2. Important things to noteShort collection of things that can trip you up badly.
Basic concepts
let info = Ifinfomsg::new(
RtAddrFamily::Unspecified,
Arphrd::Netrom,
index.unwrap_or(0) as c_int,
IffFlags::empty(),
IffFlags::empty(), // The documentation says this should always be 0xFF..FF, but that does not work!
{
let mut buffer = RtBuffer::new();
/// Adding an attribute.
buffer.push(Rtattr::new(None, Ifla::Ifname, name)?);
/// Adding an attribute with nested attributes inside.
let mut linkinfo = Rtattr::new(None, Ifla::Linkinfo, Vec::<u8>::new())?;
/// Adding the nested attribute itself.
linkinfo.add_nested_attribute(&Rtattr::new(None, IflaInfo::Kind, kind)?)?;
buffer.push(linkinfo);
buffer
},
); Concrete exampleAs mentioned before, I am trying to get bitrate setting to work at the moment. Here is how I approach the problem:
I will update this instructions as I obtain more information or based on feedback. |
Thanks for keeping at this and all the updates. My guess is that there's too much upstream work to try to get in before this is workable? So, it sounds like it won't make it in to the upcoming v2.0 release. But it is something we can target for a followup v2.1 release? |
Yeah, I think 2.0 should not wait for for the Netlink stuff - making stuff like FD support and the layout fixes available to people seems more important. I'll personally keep pecking at this topic, implementing a function/request or two when I have the time. Not sure if we need a specific milestone like a version 2.1 for this tbh. |
Unfortunately, I didn't get much done on this over the holidays, but I'm starting back on it now to get a release out. I began adding some support for the new Netlink features to the optional utility app, which I renamed to Diving into the Netlink stuff, it definitely looks like we would want to get some stuff added upstream into the I opened a new issue in the |
We'll go with what's currently in there for v2.0, and keep this issue open to add some more neli features in v2.1 |
#32 [partial] - Add set_bitrate method
Thanks to @jackyzjk for adding the required structs and enums to implement I then kept inertia going to implement most of the other netlink CAN structs etc. Just as I was finishing, it occurred to me that I could have just used bindgen, like:
But, I did use the output to adjust some of the declarations. After that I just did some copy-pasta to implement a few more setter functions and commands, like There are still more to go, but this is a good start. And it would be good to consolidate the common part of the code. |
For completeness, I'll add this... The API definitions for communicating with the kernel about CAN are in the Linux kernel sources here: And although looking at an existing client like the CAN code in iproute2 is quite helpful, it may also be useful to see the kernel code that receives and processes the netlink requests for CAN. The code is fairly small and readable: I found the top of that file particularly interesting where it maps the requests to the data type expected for each: The There is also a libsocketcan C library, with a few forks. It primarily deals with the Netlink interface. |
A number of important netlink commands are shipping with v3.1, including setting bitrate and FD data bitrate, setting control modes, manually restarting the interface, and setting an automatic restart delay time. But the implementation is still far from complete, particularly in regard to reading status and parameters back from the interface. The setter functions are also for individual parameters only, and currently there is no way to set multiple parameters in a single netlink call. Setting multiple parameters requires making a separate call for each. It would be nice to add a builder pattern, or something like that to create a single request packet for multiple parameters and send them in one call. As usual, a PR for any of this would be appreciated! Hopefully we can get some more of this implemented in v3.2. |
Does anyone know how to extract the CAN-specific parameters out of the @jreppnow , did you ever figure this out? |
@fpagliughi Can you share the bytes that you are trying to decode? I don't own a physical CAN device (privately) that I can use for testing and getting traces, but presumably the messages should have the same format as the one you use for configuration of bitrate etc. I did something similar (proprietarily) for the rust-netlink project. |
Het @jreppnow . Thanks for the quick reply. I got completely stuck on this for a day, but I think I'm starting to get it now... When requesting the CAN interface details, the CAN-specific parameters like Lines 531 to 543 in d065f83
First I was just trying to figure out how to parse down into nested attributes. I think I may be able to get it this evening. I'll post in the morning if I was able to get it working. Thanks. |
I personally really liked the way the rust-netlink project does it, including the tests which serve as examples and documentation as well: https://github.com/rust-netlink/netlink-packet-route/blob/main/src/rtnl/link/nlas/link_infos.rs#L2672 In general, all of these libraries will have a generic way to parse an attribute (NLA), which should give you the bytes (length + data) and the id, which you need to compare to the relevant constants - and then you need to know how to parse the contents (recursive NLAs, structs, values, enums,..). And then they have a way to define specific types within the library that do this parsing step for you as well and give you the above contents as Rust types - the link above does it with enums and a couple of traits (Emitable and NlaParse I think?). That should be the goal if you are developing this for a library. I've had CAN open-sourcing our CAN extension for rust-netlink on my list for a while, but I have been otherwise occupied unfortunately. |
OK. I got it. There's a really messy initial implementation up in the |
After the better part of a year, this has progressed enough to close the issue! Thanks to everyone who helped on this, especially @jreppnow and @jackyzjk. With v3.2, most of interface CAN parameters can be set or queried. There are a few minor ones that are missing; those will be added eventually as needed, or just for completeness. The low-level constants and struct bindings were kept in this crate to speed up the release, but at some point these will be pushed upstream to the |
It would be great to have full coverage of the Netlink API to interact with the CAN interfaces. Or even something better than what is already there. I don't have any experience with the Netlink CAN interfaces, so if anyone has some existing code to get it started, that would be helpful.
@marcelbuesing ? @jreppnow ?
The text was updated successfully, but these errors were encountered: