Skip to content

Commit f410fa0

Browse files
author
Valentin Obst
committed
rust/net: add CCA abstractions
Signed-off-by: Valentin Obst <[email protected]>
1 parent ded5104 commit f410fa0

File tree

4 files changed

+708
-0
lines changed

4 files changed

+708
-0
lines changed

rust/helpers.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,12 @@ struct inet_connection_sock *rust_helper_inet_csk(const struct sock *sk)
188188
}
189189
EXPORT_SYMBOL_GPL(rust_helper_inet_csk);
190190

191+
void *rust_helper_inet_csk_ca(struct sock *sk)
192+
{
193+
return inet_csk_ca(sk);
194+
}
195+
EXPORT_SYMBOL_GPL(rust_helper_inet_csk_ca);
196+
191197
/*
192198
* `bindgen` binds the C `size_t` type as the Rust `usize` type, so we can
193199
* use it in contexts where Rust expects a `usize` like slice (array) indices.

rust/kernel/net/sock.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,46 @@ impl Sock {
8989
unsafe { &mut *(bindings::tcp_sk(self.sk.get()) as *mut TcpSock) }
9090
}
9191

92+
/// Returns the [private data] of the instance of the CCA used by this
93+
/// socket.
94+
///
95+
/// [private data]: tcp::cong::Algorithm::Data
96+
///
97+
/// # Safety
98+
///
99+
/// - `sk` must be valid for `inet_csk_ca`,
100+
/// - `sk` must use the CCA `T`, the `init` CB of the CCA must have been
101+
/// called, the `release` CB of the CCA must not have been called.
102+
#[inline]
103+
#[cfg(CONFIG_RUST_TCP_ABSTRACTIONS)]
104+
pub(crate) unsafe fn inet_csk_ca<'a, T: tcp::cong::Algorithm + ?Sized>(
105+
&'a self,
106+
) -> &'a T::Data {
107+
// SAFETY: By the function's preconditions, calling `inet_csk_ca` is OK
108+
// and the returned pointer points to a valid instance of `T::Data`.
109+
unsafe { &*(bindings::inet_csk_ca(self.sk.get()) as *const T::Data) }
110+
}
111+
112+
/// Returns the [private data] of the instance of the CCA used by this
113+
/// socket.
114+
///
115+
/// [private data]: tcp::cong::Algorithm::Data
116+
///
117+
/// # Safety
118+
///
119+
/// - `sk` must be valid for `inet_csk_ca`,
120+
/// - `sk` must use the CCA `T`, the `init` CB of the CCA must have been
121+
/// called, the `release` CB of the CCA must not have been called.
122+
#[inline]
123+
#[cfg(CONFIG_RUST_TCP_ABSTRACTIONS)]
124+
pub(crate) unsafe fn inet_csk_ca_mut<'a, T: tcp::cong::Algorithm + ?Sized>(
125+
&'a mut self,
126+
) -> &'a mut T::Data {
127+
// SAFETY: By the function's preconditions, calling `inet_csk_ca` is OK
128+
// and the returned pointer points to a valid instance of `T::Data`.
129+
unsafe { &mut *(bindings::inet_csk_ca(self.sk.get()) as *mut T::Data) }
130+
}
131+
92132
/// Returns the [`InetConnectionSock`] view of this socket.
93133
///
94134
/// # Safety

rust/kernel/net/tcp.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use crate::time;
66
use crate::types::Opaque;
77
use core::{num, ptr};
88

9+
pub mod cong;
10+
911
/// Representation of a `struct inet_connection_sock`.
1012
///
1113
/// # Invariants
@@ -20,6 +22,21 @@ pub struct InetConnectionSock {
2022
icsk: Opaque<bindings::inet_connection_sock>,
2123
}
2224

25+
impl InetConnectionSock {
26+
/// Returns the congestion control state of this socket.
27+
#[inline]
28+
pub fn ca_state(&self) -> Result<cong::State, ()> {
29+
const CA_STATE_MASK: u8 = 0b11111;
30+
// TODO: Replace code to access the bit field with automatically
31+
// generated code by bindgen when it becomes possible.
32+
// SAFETY: By the type invariants, it is okay to read `icsk_ca_state`, which is the first
33+
// member of the bitfield and has a size of five.
34+
cong::State::try_from(unsafe {
35+
*(ptr::addr_of!((*self.icsk.get())._bitfield_1).cast::<u8>()) & CA_STATE_MASK
36+
})
37+
}
38+
}
39+
2340
/// Representation of a `struct tcp_sock`.
2441
///
2542
/// # Invariants

0 commit comments

Comments
 (0)