netlink-packet-connector

Crates.ionetlink-packet-connector
lib.rsnetlink-packet-connector
version0.1.0
created_at2025-07-13 15:45:09.300678+00
updated_at2025-07-13 15:45:09.300678+00
descriptionAn implementation of the Linux kernel Connector API using netlink-packet-core.
homepage
repositoryhttps://gitlab.com/hpi-potsdam/osm/webassembly-kernel-runtime/netlink-packet-connector
max_upload_size
id1750600
size22,626
Sebastian (Encotric)

documentation

README

Connector API implementation

This crate implements the Netlink-based Connector API used for communication between Linux kernel and user space.

To do so, it relies on the netlink-packet-core crate and is aligned to the rust-netlink crates.

An example usage could look like the following:

use bytes::Buf;
use log::info;
use netlink_packet_connector::protocol::ConnectorMessage;
use netlink_packet_core::{NetlinkBuffer, NetlinkDeserializable, NetlinkMessage, NetlinkPayload};
use netlink_sys::{protocols::NETLINK_CONNECTOR, Socket, SocketAddr};

fn main() {
    // Example connector API message with seq number 1234 and a single byte data payload.s
    let connector_message = ConnectorMessage::new(15, 1001, 1234, 0, 0, vec![1]);
    let mut nl_msg = NetlinkMessage::from(connector_message);
    nl_msg.finalize();

    let mut buf = vec![0; 1024 * 8];
    nl_msg.serialize(&mut buf[..nl_msg.buffer_len()]);

    // ... `socket` is a netlink socket
    socket.bind(&kernel_unicast).unwrap();
    socket.add_membership(14).unwrap();

    socket.send(&buf[..nl_msg.buffer_len()], 0).unwrap();

    info!("WebAssembly runtime CLI started!");

    let mut buf = Vec::with_capacity(1024 * 8);

    let n = socket.recv(&mut buf, 0).unwrap();
    // This dance with the NetlinkBuffer should not be
    // necessary. It is here to work around a netlink bug. See:
    // https://github.com/mozilla/libaudit-go/issues/24
    // https://github.com/linux-audit/audit-userspace/issues/78
    {
        let mut nl_buf = NetlinkBuffer::new(&mut buf[0..n]);
        if n != nl_buf.length() as usize {
            nl_buf.set_length(n as u32);
        }
    }

    // Parse an received Connector API message
    let parsed = NetlinkMessage::<ConnectorMessage>::deserialize(&buf[0..n]).unwrap();

    match parsed.payload {
        NetlinkPayload::InnerMessage(connector_msg) => {
            info!("Received connector message: {:?}", connector_msg.data());
        }
        NetlinkPayload::Done(msg) => {
            let mut payload = msg.code.to_ne_bytes().to_vec();
            payload.extend_from_slice(&msg.extended_ack);

            let connector_ack = ConnectorMessage::deserialize(&parsed.header, &payload).unwrap();
            info!("Received connector ack: {:?}", connector_ack.data());
            // TODO: do something
        }
        _ => {
            info!("Received something else: {:?}", parsed);
        }
    }
}

Commit count: 0

cargo fmt