[PATCH 1/4] rust: netlink: add raw netlink abstraction

Alice Ryhl posted 4 patches 1 month ago
There is a newer version of this series
Re: [PATCH 1/4] rust: netlink: add raw netlink abstraction
Posted by Andrew Lunn 1 month ago
> diff --git a/rust/kernel/netlink.rs b/rust/kernel/netlink.rs

...

> +/// The default netlink message size.
> +pub const GENLMSG_DEFAULT_SIZE: usize = bindings::GENLMSG_DEFAULT_SIZE;
> +
> +/// A wrapper around `struct sk_buff` for generic netlink messages.
> +///
> +/// # Invariants
> +///
> +/// The pointer has ownership over a valid `sk_buff`.
> +pub struct SkBuff {
> +    skb: NonNull<kernel::bindings::sk_buff>,
> +}

struct sk_buff is a core data structure which appears all over the
networking stack, but also other places like crypto, scsi, tty, file
systems, etc. Since it is a top level data structure, it seems odd
Rust puts it into netlink.rs.

How do you see the Rust SkBuff evolving to a general purpose data
structure which can be used everywhere?

	  Andrew
Re: [PATCH 1/4] rust: netlink: add raw netlink abstraction
Posted by Alice Ryhl 1 month ago
On Sat, Mar 07, 2026 at 04:43:02PM +0100, Andrew Lunn wrote:
> > diff --git a/rust/kernel/netlink.rs b/rust/kernel/netlink.rs
> 
> ...
> 
> > +/// The default netlink message size.
> > +pub const GENLMSG_DEFAULT_SIZE: usize = bindings::GENLMSG_DEFAULT_SIZE;
> > +
> > +/// A wrapper around `struct sk_buff` for generic netlink messages.
> > +///
> > +/// # Invariants
> > +///
> > +/// The pointer has ownership over a valid `sk_buff`.
> > +pub struct SkBuff {
> > +    skb: NonNull<kernel::bindings::sk_buff>,
> > +}
> 
> struct sk_buff is a core data structure which appears all over the
> networking stack, but also other places like crypto, scsi, tty, file
> systems, etc. Since it is a top level data structure, it seems odd
> Rust puts it into netlink.rs.
> 
> How do you see the Rust SkBuff evolving to a general purpose data
> structure which can be used everywhere?

We can make a kernel::net module (rust/kernel/net/) and put it there
instead? I guess netlink.rs can also be a submodule of that.

Hmm ... but I'm currently using genlmsg_new() / nlmsg_free(), and I
assume the other use-cases do not go through those methods, since they
sound netlink specific.

To be honest, I'm new to the kernel's networking stack, so I probably
can't design Rust wrapper for sk_buff that supports all those different
usecases without someone walking me through how it works. It may or may
not be best to write a netlink-specific struct now and expand it later.

Alice
Re: [PATCH 1/4] rust: netlink: add raw netlink abstraction
Posted by Andrew Lunn 1 month ago
> We can make a kernel::net module (rust/kernel/net/) and put it there
> instead? I guess netlink.rs can also be a submodule of that.
> 
> Hmm ... but I'm currently using genlmsg_new() / nlmsg_free(), and I
> assume the other use-cases do not go through those methods, since they
> sound netlink specific.
> 
> To be honest, I'm new to the kernel's networking stack, so I probably
> can't design Rust wrapper for sk_buff that supports all those different
> usecases without someone walking me through how it works. It may or may
> not be best to write a netlink-specific struct now and expand it later.

At its core, an skbuff represents a block of memory. Normally that
memory would be packet data flowing through the network stack. You can
append to the front and back of the data in the buffer. You can add
the buffer to linked lists, there are reference counting operations,
so the buffer can have multiple users, there are places you can store
per protocol data, and places you can store data while within one
protocol layer, etc.

When using sk_buff for packet data, you are generally on a fast path,
so much of the code is in header files as inline functions. This is
going to make rust binding harder, my current understanding is that it
is hard to make use of such functions from rust.

However, for netlink, its is slow path code, it seems like all the
functions you need to call are in object files, not inline headers.

I also suspect, but don't know, that the netlink upper API is disjoint
to the packet handling upper API. How you allocate a skbuff for
netlink is different to packet data. It is very likely an error if you
try to transmit out an interface an skbuff allocated for netlink
usage, etc.

So, maybe you can have a base definition of skbuff in rust/kernel/net,
and build on top of that to make a netlink specific skbuff, with a
limited list of methods which can access it, those needed for netlink?
Make use of the Rust type system? And leave the messy fast path packet
data things for somebody else.

     Andrew
Re: [PATCH 1/4] rust: netlink: add raw netlink abstraction
Posted by Alice Ryhl 1 month ago
On Sun, Mar 08, 2026 at 03:48:40PM +0100, Andrew Lunn wrote:
> > We can make a kernel::net module (rust/kernel/net/) and put it there
> > instead? I guess netlink.rs can also be a submodule of that.
> > 
> > Hmm ... but I'm currently using genlmsg_new() / nlmsg_free(), and I
> > assume the other use-cases do not go through those methods, since they
> > sound netlink specific.
> > 
> > To be honest, I'm new to the kernel's networking stack, so I probably
> > can't design Rust wrapper for sk_buff that supports all those different
> > usecases without someone walking me through how it works. It may or may
> > not be best to write a netlink-specific struct now and expand it later.
> 
> At its core, an skbuff represents a block of memory. Normally that
> memory would be packet data flowing through the network stack. You can
> append to the front and back of the data in the buffer. You can add
> the buffer to linked lists, there are reference counting operations,
> so the buffer can have multiple users, there are places you can store
> per protocol data, and places you can store data while within one
> protocol layer, etc.
> 
> When using sk_buff for packet data, you are generally on a fast path,
> so much of the code is in header files as inline functions. This is
> going to make rust binding harder, my current understanding is that it
> is hard to make use of such functions from rust.
> 
> However, for netlink, its is slow path code, it seems like all the
> functions you need to call are in object files, not inline headers.

There are several static inline methods that I need to call. Here is the
list:

- genlmsg_new
- genlmsg_multicast
- genlmsg_cancel
- genlmsg_end
- nlmsg_free
- genl_has_listeners

And on Android devices running this code, they will in fact have been
inlined into Rust code, permitting fast code without function call
overhead. Inlining happens via my other (recent) patchset [1], which the
Android kernel is already using in production.

[1]: https://lore.kernel.org/all/20260203-inline-helpers-v2-0-beb8547a03c9@google.com/

> I also suspect, but don't know, that the netlink upper API is disjoint
> to the packet handling upper API. How you allocate a skbuff for
> netlink is different to packet data. It is very likely an error if you
> try to transmit out an interface an skbuff allocated for netlink
> usage, etc.

If that is the case, then it sounds like the correct API design would be
to have a separate NetlinkSkBuff type so that you cannot mix them up
with an sk_buff used for packet data.

> So, maybe you can have a base definition of skbuff in rust/kernel/net,
> and build on top of that to make a netlink specific skbuff, with a
> limited list of methods which can access it, those needed for netlink?
> Make use of the Rust type system? And leave the messy fast path packet
> data things for somebody else.

That makes sense to me. If there is duplication between the two sk_buff
types, then one can be defined in terms of the other (or maybe it's
easier to not do that).

Alice
Re: [PATCH 1/4] rust: netlink: add raw netlink abstraction
Posted by Andrew Lunn 1 month ago
> There are several static inline methods that I need to call. Here is the
> list:
> 
> - genlmsg_new
> - genlmsg_multicast
> - genlmsg_cancel
> - genlmsg_end
> - nlmsg_free
> - genl_has_listeners
> 
> And on Android devices running this code, they will in fact have been
> inlined into Rust code, permitting fast code without function call
> overhead. Inlining happens via my other (recent) patchset [1], which the
> Android kernel is already using in production.
> 
> [1]: https://lore.kernel.org/all/20260203-inline-helpers-v2-0-beb8547a03c9@google.com/

Ah, cool. That is going to be very useful in networking.

> If that is the case, then it sounds like the correct API design would be
> to have a separate NetlinkSkBuff type so that you cannot mix them up
> with an sk_buff used for packet data.
> 
> > So, maybe you can have a base definition of skbuff in rust/kernel/net,
> > and build on top of that to make a netlink specific skbuff, with a
> > limited list of methods which can access it, those needed for netlink?
> > Make use of the Rust type system? And leave the messy fast path packet
> > data things for somebody else.
> 
> That makes sense to me. If there is duplication between the two sk_buff
> types, then one can be defined in terms of the other (or maybe it's
> easier to not do that).

Probably struct sk_buff is one of those complex things where we make
our best guess design now, and be prepared to redesign and refactor
the code as we learn more. To me, it feels like we need a base SkBuff
with full access to all API methods. And then a restricted type for
NetlinkSkBuff on top of that for users of netlink.

	Andrew
Re: [PATCH 1/4] rust: netlink: add raw netlink abstraction
Posted by Alice Ryhl 1 month ago
On Sun, Mar 08, 2026 at 06:24:16PM +0100, Andrew Lunn wrote:
> > If that is the case, then it sounds like the correct API design would be
> > to have a separate NetlinkSkBuff type so that you cannot mix them up
> > with an sk_buff used for packet data.
> > 
> > > So, maybe you can have a base definition of skbuff in rust/kernel/net,
> > > and build on top of that to make a netlink specific skbuff, with a
> > > limited list of methods which can access it, those needed for netlink?
> > > Make use of the Rust type system? And leave the messy fast path packet
> > > data things for somebody else.
> > 
> > That makes sense to me. If there is duplication between the two sk_buff
> > types, then one can be defined in terms of the other (or maybe it's
> > easier to not do that).
> 
> Probably struct sk_buff is one of those complex things where we make
> our best guess design now, and be prepared to redesign and refactor
> the code as we learn more. To me, it feels like we need a base SkBuff
> with full access to all API methods. And then a restricted type for
> NetlinkSkBuff on top of that for users of netlink.

Agreed. Though in this patchset, I don't believe I use any of the base
skbuff methods, except for the fact that the nlmsg methods seem to wrap
them. So it is probably dead code to add much right now unless I bypass
the nlmsg wrappers.

Alice