-
Notifications
You must be signed in to change notification settings - Fork 47
Open
Description
Version of neli
Both 0.7.1 and commit dbacf64
Describe the bug
Failure to deserialize a new neighbor notification.
To Reproduce
Steps to reproduce the behavior:
- Run this program as root:
use std::error::Error;
use neli::consts::socket::NlFamily;
use neli::router::synchronous::NlRouter;
use neli::utils::Groups;
const RTMGRP_NOTIFY: u32 = 2;
const RTMGRP_NEIGH: u32 = 4;
fn main() -> Result<(), Box<dyn Error>> {
simple_logger::SimpleLogger::new()
.env()
.init()
.expect("Failure to initialize simpler_logger");
let nl_rte_groups = Groups::new_bitmask(RTMGRP_NEIGH | RTMGRP_NOTIFY);
let (nl_rte_router, nl_recv_handle) =
NlRouter::connect(NlFamily::Route, None, nl_rte_groups)
.map_err(|e| format!("Failed to connect to netlink: {e}"))?;
nl_rte_router.enable_strict_checking(false)?;
println!("Waiting for netlink notifications.");
for maybe_msghdr in nl_recv_handle {
match maybe_msghdr {
Err(e) => eprintln!("Failed to receive netlink message header: {e}"),
Ok(msghdr) => println!("{:?}", msghdr),
};
}
Ok(())
}
- Run this command:
sudo ip neigh add 192.168.148.181 lladdr ca:bd:31:de:dc:c7 dev wlp4s0
- Observe deserialization error:
2025-10-06T22:15:30.831Z TRACE [neli::utils::synchronous] Semaphore acquired; current count is 1, available is 2
2025-10-06T22:15:32.962Z TRACE [neli::socket::synchronous] Buffer received: [76, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 68, 0, 16, 0, 2, 0, 0, 0, 3, 0, 0, 0, 128, 0, 0, 1, 8, 0, 1, 0, 192, 168, 148, 181, 10, 0, 2, 0, 202, 189, 49, 222, 220, 199, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 20, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
2025-10-06T22:15:32.962Z TRACE [neli::nl] Deserializing data type Nlmsghdr
2025-10-06T22:15:32.962Z TRACE [neli::nl] Deserializing field type u32
2025-10-06T22:15:32.962Z TRACE [neli::nl] Buffer to be deserialized: [76, 0, 0, 0]
2025-10-06T22:15:32.962Z TRACE [neli::nl] Field deserialized: 76
2025-10-06T22:15:32.962Z TRACE [neli::nl] Deserializing field type u16
2025-10-06T22:15:32.962Z TRACE [neli::nl] Buffer to be deserialized: [28, 0]
2025-10-06T22:15:32.962Z TRACE [neli::nl] Field deserialized: 28
2025-10-06T22:15:32.962Z TRACE [neli::nl] Deserializing field type neli::consts::nl::NlmF
2025-10-06T22:15:32.962Z TRACE [neli::nl] Buffer to be deserialized: [0, 0]
2025-10-06T22:15:32.962Z TRACE [neli::consts::nl] Deserializing data type NlmF
2025-10-06T22:15:32.962Z TRACE [neli::consts::nl] Deserializing field type u16
2025-10-06T22:15:32.962Z TRACE [neli::consts::nl] Buffer to be deserialized: [0, 0]
2025-10-06T22:15:32.962Z TRACE [neli::consts::nl] Field deserialized: 0
2025-10-06T22:15:32.962Z TRACE [neli::nl] Field deserialized: NlmF(0)
2025-10-06T22:15:32.962Z TRACE [neli::nl] Deserializing field type u32
2025-10-06T22:15:32.962Z TRACE [neli::nl] Buffer to be deserialized: [0, 0, 0, 0]
2025-10-06T22:15:32.962Z TRACE [neli::nl] Field deserialized: 0
2025-10-06T22:15:32.962Z TRACE [neli::nl] Deserializing field type u32
2025-10-06T22:15:32.962Z TRACE [neli::nl] Buffer to be deserialized: [68, 0, 16, 0]
2025-10-06T22:15:32.962Z TRACE [neli::nl] Field deserialized: 1048644
2025-10-06T22:15:32.962Z TRACE [neli::nl] Deserializing field type neli::nl::NlPayload<u16, neli::types::Buffer>
2025-10-06T22:15:32.962Z TRACE [neli::nl] Buffer to be deserialized: [2, 0, 0, 0, 3, 0, 0, 0, 128, 0, 0, 1, 8, 0, 1, 0, 192, 168, 148, 181, 10, 0, 2, 0, 202, 189, 49, 222, 220, 199, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 20, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
2025-10-06T22:15:32.962Z TRACE [neli::nl] Deserializing data type neli::nl::NlPayload<u16, neli::types::Buffer>
2025-10-06T22:15:32.962Z TRACE [neli::nl] Field deserialized: Payload(Buffer)
2025-10-06T22:15:32.962Z TRACE [neli::iter] Message received: Nlmsghdr { nl_len: 76, nl_type: 28, nl_flags: NlmF(0), nl_seq: 0, nl_pid: 1048644, nl_payload: Payload(Buffer) }
2025-10-06T22:15:32.962Z TRACE [neli::router::synchronous] Message received: Ok(Nlmsghdr { nl_len: 76, nl_type: 28, nl_flags: NlmF(0), nl_seq: 0, nl_pid: 1048644, nl_payload: Payload(Buffer) })
2025-10-06T22:15:32.962Z TRACE [neli::genl] Deserializing data type Genlmsghdr
2025-10-06T22:15:32.962Z TRACE [neli::genl] Deserializing field type u8
2025-10-06T22:15:32.962Z TRACE [neli::genl] Buffer to be deserialized: [2]
2025-10-06T22:15:32.962Z TRACE [neli::genl] Field deserialized: 2
2025-10-06T22:15:32.962Z TRACE [neli::genl] Deserializing field type u8
2025-10-06T22:15:32.962Z TRACE [neli::genl] Buffer to be deserialized: [0]
2025-10-06T22:15:32.962Z TRACE [neli::genl] Field deserialized: 0
2025-10-06T22:15:32.962Z TRACE [neli::genl] Deserializing field type u16
2025-10-06T22:15:32.963Z TRACE [neli::genl] Buffer to be deserialized: [0, 0]
2025-10-06T22:15:32.963Z TRACE [neli::genl] Field deserialized: 0
2025-10-06T22:15:32.963Z TRACE [neli::genl] Deserializing field type neli::genl::NoUserHeader
2025-10-06T22:15:32.963Z TRACE [neli::genl] Buffer to be deserialized: []
2025-10-06T22:15:32.963Z TRACE [neli::genl] Field deserialized: NoUserHeader
2025-10-06T22:15:32.963Z TRACE [neli::genl] Deserializing field type neli::types::GenlBuffer<u16, neli::types::Buffer>
2025-10-06T22:15:32.963Z TRACE [neli::genl] Buffer to be deserialized: [3, 0, 0, 0, 128, 0, 0, 1, 8, 0, 1, 0, 192, 168, 148, 181, 10, 0, 2, 0, 202, 189, 49, 222, 220, 199, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 20, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
2025-10-06T22:15:32.963Z TRACE [neli::types] Deserializing data type GenlBuffer
2025-10-06T22:15:32.963Z TRACE [neli::types] Deserializing field type alloc::vec::Vec<neli::genl::Nlattr<u16, neli::types::Buffer>>
2025-10-06T22:15:32.963Z TRACE [neli::types] Buffer to be deserialized: [3, 0, 0, 0, 128, 0, 0, 1, 8, 0, 1, 0, 192, 168, 148, 181, 10, 0, 2, 0, 202, 189, 49, 222, 220, 199, 0, 0, 8, 0, 4, 0, 0, 0, 0, 0, 20, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
2025-10-06T22:15:32.963Z TRACE [neli::genl] Deserializing data type Nlattr
2025-10-06T22:15:32.963Z TRACE [neli::genl] Deserializing field type u16
2025-10-06T22:15:32.963Z TRACE [neli::genl] Buffer to be deserialized: [3, 0]
2025-10-06T22:15:32.963Z TRACE [neli::genl] Field deserialized: 3
2025-10-06T22:15:32.963Z TRACE [neli::genl] Deserializing field type neli::genl::AttrType<u16>
2025-10-06T22:15:32.963Z TRACE [neli::genl] Buffer to be deserialized: [0, 0]
2025-10-06T22:15:32.963Z TRACE [neli::genl] Field deserialized: AttrType { nla_nested: false, nla_network_order: false, nla_type: 0 }
Failed to receive netlink message header: Deserialization failed: Invalid input was provided: 3
Please provide a minimal, ready-to-compile example that reproduces the bug
See above.
Expected behavior
- I expect this message to deserialize okay since it was authored by the kernel.
- I also expect the
NlRouterReceiveHandleto be able to continue receiving additional messages. In other words, I am surprised this is considered a fatal error.
Additional context
Test on kernel: 6.16.7+deb14-amd64
Compiled with rust 1.89.0
I used an nlmon device to capture netlink traffix while running a similar ip neigh add command. Based on the wireshark decoding of those packets, I believe the 3 in the neli trace is supposed to be the interface index:
