Skip to content

Commit 0aadcd6

Browse files
committed
rust_binder: add generated netlink.rs file
To use netlink from Rust Binder, add a new generated netlink file using the new script and Documentation/netlink/specs/binder.yaml. Signed-off-by: Alice Ryhl <aliceryhl@google.com>
1 parent 44dd2fb commit 0aadcd6

4 files changed

Lines changed: 122 additions & 3 deletions

File tree

drivers/android/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ config ANDROID_BINDER_IPC
1616

1717
config ANDROID_BINDER_IPC_RUST
1818
bool "Rust version of Android Binder IPC Driver"
19-
depends on RUST && MMU && !ANDROID_BINDER_IPC
19+
depends on RUST && MMU && NET && !ANDROID_BINDER_IPC
2020
help
2121
This enables the Rust implementation of the Binder driver.
2222

drivers/android/binder/netlink.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
2+
/* Do not edit directly, auto-generated from: */
3+
/* Documentation/netlink/specs/binder.yaml */
4+
/* YNL-GEN rust source */
5+
/* To regenerate run: tools/net/ynl/ynl-regen.sh */
6+
7+
#![allow(unreachable_pub, clippy::wrong_self_convention)]
8+
use kernel::netlink::{Family, MulticastGroup};
9+
use kernel::prelude::*;
10+
11+
pub static BINDER_NL_FAMILY: Family = Family::const_new(
12+
&crate::THIS_MODULE,
13+
kernel::uapi::BINDER_FAMILY_NAME,
14+
kernel::uapi::BINDER_FAMILY_VERSION,
15+
&BINDER_NL_FAMILY_MCGRPS,
16+
);
17+
18+
static BINDER_NL_FAMILY_MCGRPS: [MulticastGroup; 1] = [MulticastGroup::const_new(c"report")];
19+
20+
/// A multicast event sent to userspace subscribers to notify them about
21+
/// binder transaction failures. The generated report provides the full
22+
/// details of the specific transaction that failed. The intention is for
23+
/// programs to monitor these events and react to the failures as needed.
24+
pub struct Report {
25+
skb: kernel::netlink::GenlMsg,
26+
}
27+
28+
impl Report {
29+
/// Create a new multicast message.
30+
pub fn new(
31+
size: usize,
32+
portid: u32,
33+
seq: u32,
34+
flags: kernel::alloc::Flags,
35+
) -> Result<Self, kernel::alloc::AllocError> {
36+
const BINDER_CMD_REPORT: u8 = kernel::uapi::BINDER_CMD_REPORT as u8;
37+
let skb = kernel::netlink::NetlinkSkBuff::new(size, flags)?;
38+
let skb = skb.genlmsg_put(portid, seq, &BINDER_NL_FAMILY, BINDER_CMD_REPORT)?;
39+
Ok(Self { skb })
40+
}
41+
42+
/// Broadcast this message.
43+
pub fn multicast(self, portid: u32, flags: kernel::alloc::Flags) -> Result {
44+
self.skb.multicast(&BINDER_NL_FAMILY, portid, 0, flags)
45+
}
46+
47+
/// Check if this message type has listeners.
48+
pub fn has_listeners() -> bool {
49+
BINDER_NL_FAMILY.has_listeners(0)
50+
}
51+
52+
/// The enum binder_driver_return_protocol returned to the sender.
53+
pub fn error(&mut self, val: u32) -> Result {
54+
const BINDER_A_REPORT_ERROR: c_int = kernel::uapi::BINDER_A_REPORT_ERROR as c_int;
55+
self.skb.put_u32(BINDER_A_REPORT_ERROR, val)
56+
}
57+
58+
/// The binder context where the transaction occurred.
59+
pub fn context(&mut self, val: &CStr) -> Result {
60+
const BINDER_A_REPORT_CONTEXT: c_int = kernel::uapi::BINDER_A_REPORT_CONTEXT as c_int;
61+
self.skb.put_string(BINDER_A_REPORT_CONTEXT, val)
62+
}
63+
64+
/// The PID of the sender process.
65+
pub fn from_pid(&mut self, val: u32) -> Result {
66+
const BINDER_A_REPORT_FROM_PID: c_int = kernel::uapi::BINDER_A_REPORT_FROM_PID as c_int;
67+
self.skb.put_u32(BINDER_A_REPORT_FROM_PID, val)
68+
}
69+
70+
/// The TID of the sender thread.
71+
pub fn from_tid(&mut self, val: u32) -> Result {
72+
const BINDER_A_REPORT_FROM_TID: c_int = kernel::uapi::BINDER_A_REPORT_FROM_TID as c_int;
73+
self.skb.put_u32(BINDER_A_REPORT_FROM_TID, val)
74+
}
75+
76+
/// The PID of the recipient process. This attribute may not be present
77+
/// if the target could not be determined.
78+
pub fn to_pid(&mut self, val: u32) -> Result {
79+
const BINDER_A_REPORT_TO_PID: c_int = kernel::uapi::BINDER_A_REPORT_TO_PID as c_int;
80+
self.skb.put_u32(BINDER_A_REPORT_TO_PID, val)
81+
}
82+
83+
/// The TID of the recipient thread. This attribute may not be present
84+
/// if the target could not be determined.
85+
pub fn to_tid(&mut self, val: u32) -> Result {
86+
const BINDER_A_REPORT_TO_TID: c_int = kernel::uapi::BINDER_A_REPORT_TO_TID as c_int;
87+
self.skb.put_u32(BINDER_A_REPORT_TO_TID, val)
88+
}
89+
90+
/// When present, indicates the failed transaction is a reply.
91+
pub fn is_reply(&mut self) -> Result {
92+
const BINDER_A_REPORT_IS_REPLY: c_int = kernel::uapi::BINDER_A_REPORT_IS_REPLY as c_int;
93+
self.skb.put_flag(BINDER_A_REPORT_IS_REPLY)
94+
}
95+
96+
/// The bitmask of enum transaction_flags from the transaction.
97+
pub fn flags(&mut self, val: u32) -> Result {
98+
const BINDER_A_REPORT_FLAGS: c_int = kernel::uapi::BINDER_A_REPORT_FLAGS as c_int;
99+
self.skb.put_u32(BINDER_A_REPORT_FLAGS, val)
100+
}
101+
102+
/// The application-defined code from the transaction.
103+
pub fn code(&mut self, val: u32) -> Result {
104+
const BINDER_A_REPORT_CODE: c_int = kernel::uapi::BINDER_A_REPORT_CODE as c_int;
105+
self.skb.put_u32(BINDER_A_REPORT_CODE, val)
106+
}
107+
108+
/// The transaction payload size in bytes.
109+
pub fn data_size(&mut self, val: u32) -> Result {
110+
const BINDER_A_REPORT_DATA_SIZE: c_int = kernel::uapi::BINDER_A_REPORT_DATA_SIZE as c_int;
111+
self.skb.put_u32(BINDER_A_REPORT_DATA_SIZE, val)
112+
}
113+
}

drivers/android/binder/rust_binder_main.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ mod context;
3636
mod deferred_close;
3737
mod defs;
3838
mod error;
39+
#[allow(dead_code)]
40+
mod netlink;
3941
mod node;
4042
mod page_range;
4143
mod process;
@@ -286,19 +288,22 @@ fn ptr_align(value: usize) -> Option<usize> {
286288
// SAFETY: We call register in `init`.
287289
static BINDER_SHRINKER: Shrinker = unsafe { Shrinker::new() };
288290

289-
struct BinderModule {}
291+
struct BinderModule {
292+
_netlink: kernel::netlink::Registration,
293+
}
290294

291295
impl kernel::Module for BinderModule {
292296
fn init(_module: &'static kernel::ThisModule) -> Result<Self> {
293297
// SAFETY: The module initializer never runs twice, so we only call this once.
294298
unsafe { crate::context::CONTEXTS.init() };
295299

300+
let netlink = crate::netlink::BINDER_NL_FAMILY.register()?;
296301
BINDER_SHRINKER.register(c"android-binder")?;
297302

298303
// SAFETY: The module is being loaded, so we can initialize binderfs.
299304
unsafe { kernel::error::to_result(binderfs::init_rust_binderfs())? };
300305

301-
Ok(Self {})
306+
Ok(Self { _netlink: netlink })
302307
}
303308
}
304309

rust/uapi/uapi_helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <uapi/drm/nova_drm.h>
1212
#include <uapi/drm/panthor_drm.h>
1313
#include <uapi/linux/android/binder.h>
14+
#include <uapi/linux/android/binder_netlink.h>
1415
#include <uapi/linux/mdio.h>
1516
#include <uapi/linux/mii.h>
1617
#include <uapi/linux/ethtool.h>

0 commit comments

Comments
 (0)