-
Notifications
You must be signed in to change notification settings - Fork 167
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 socket protocols are largely actually socket options, which are also missing #1252
Comments
I don't know how it could be possible to expose a lower-level API while still having any of the benefits of type, memory, or I/O safety. To provide a safe interface, rustix has to know which arguments are pointers, which are file descriptors, what memory is to be mutated, and so on. Rustix once attempted to expose only typed interfaces to ioctls for this reason, however there are just too many ioctls for it to be practical to cover them all, so Rustix now exposes a generic It's telling that the very first sentence in the netlink book describes netlink as an ioctl replacement. I would like to add a feature to Rustix that just exposes raw socket features as an unsafe interface. We can still add safe interfaces for features as we're able to, but the unsafe interface will be there for everything else. I don't yet know what that should look like, and would appreciate any help anyone might be able to offer. |
Unless I'm mistaken, all of this is known in advance and perfectly safe for at least AIUI socket options are at least always plain old data, so in my mind this can be a perfectly safe interface taking opaque bytes, unless theres some evil socket options that modify This leaves all the benefits of the errno handling, I/O safety for the passed FD, memory safety for the buffers, type safety for the levels and option names, with corresponding Raw types and The levels and option names can even be paired into some sort of struct SocketOption {
level: SocketOptionLevel, // i32
name: SocketOptionName, // i32
}
pub fn setsockopt(fd: &BorrowedFd, opt: SocketOption, value: &[u8]) -> Result<()>;
pub fn getsockopt(fd: &BorrowedFd, opt: SocketOption, value: &mut [u8]) -> Result<()>;
mod netlink {
pub const CAP_ACK: SocketOption = SocketOption::from_raw(SOL_NETLINK, NETLINK_CAP_ACK);
}
// usage:
setsockopt(&socket, netlink::CAP_ACK, &0u32.to_ne_bytes()[..]); This is still low level in the sense of being a straight-forward wrapper around the direct syscall which the caller still needs to know how to use, but is perfectly safe in rust terms and lagely benefits from the various other safeties(type, I/O) and clear intent signaling of rustix, and can form the basis of a higher level wrapper that knows about the option/value pairing from rustix or other crates.(I don't think its rustix style, but I like the idea of type-state generics for this.) |
That's a good point. And I guess it's ok even if Linux adds arbitrary new types in the future, because users still need an |
https://docs.rs/rustix/0.38.42/rustix/net/sockopt/index.html
Many of the supposed netlink protocols are in reality netlink specific socket options, which are also completely missing in the sockopt module
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.ADD_MEMBERSHIP.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.DROP_MEMBERSHIP.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.LIST_MEMBERSHIPS.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.BROADCAST_ERROR.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.NO_ENOBUFS.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.CAP_ACK.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.EXT_ACK.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.GET_STRICT_CHK.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.LISTEN_ALL_NSID.html
https://docs.rs/rustix/0.38.42/rustix/net/netlink/constant.PKTINFO.html
all of these are socket options described in
netlink.7
or the netlink handbook.Additionally, when I read rustix was low-level and "aims to provide safe and idiomatic Rust interfaces to low-level syscalls", I was surprised to find no direct interface to many syscalls, but instead high level wrappers exclusively exposing specific subsets of them that rustix knows about, and nothing for those it doesn't.
I was expecting a lower level API to syscalls like this, with all the benefits of type, memory, and I/O safety rustix provides over the raw syscalls and bare integers, but that doesn't seem to be a design goal for rustix.
The text was updated successfully, but these errors were encountered: