Skip to content

Commit d829f50

Browse files
committed
socket::sockopt AttachReusePortCbpf for Linux addition.
Set a BPF program to the socket to set how packets are handled within the reuseport group.
1 parent ea012be commit d829f50

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

changelog/2621.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added `socket::sockopt::AttachReusePortCbpf` for Linux

src/sys/socket/sockopt.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,18 @@ sockopt_impl!(
12691269
libc::SO_EXCLBIND,
12701270
bool
12711271
);
1272+
#[cfg(target_os = "linux")]
1273+
sockopt_impl!(
1274+
/// To be used with `ReusePort`,
1275+
/// we can then attach a BPF (classic)
1276+
/// to set how the packets are assigned
1277+
/// to the socket (e.g. cpu distribution).
1278+
AttachReusePortCbpf,
1279+
SetOnly,
1280+
libc::SOL_SOCKET,
1281+
libc::SO_ATTACH_REUSEPORT_CBPF,
1282+
libc::sock_fprog
1283+
);
12721284

12731285
#[allow(missing_docs)]
12741286
// Not documented by Linux!

test/sys/test_sockopt.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,3 +1194,28 @@ fn test_solfilter() {
11941194
assert_eq!(Err(Errno::ENOENT), setsockopt(&s, attach, data));
11951195
assert_eq!(Err(Errno::ENOENT), setsockopt(&s, detach, data));
11961196
}
1197+
1198+
#[cfg(target_os = "linux")]
1199+
#[test]
1200+
pub fn test_so_attach_reuseport_cbpf() {
1201+
let fd = socket(
1202+
AddressFamily::Inet6,
1203+
SockType::Datagram,
1204+
SockFlag::empty(),
1205+
None,
1206+
)
1207+
.unwrap();
1208+
setsockopt(&fd, sockopt::ReusePort, &true).unwrap();
1209+
setsockopt(&fd, sockopt::ReuseAddr, &true).unwrap();
1210+
let mut flt: [libc::sock_filter; 2] = unsafe { std::mem::zeroed() };
1211+
flt[0].code = (libc::BPF_LD | libc::BPF_W | libc::BPF_ABS) as u16;
1212+
flt[0].k = (libc::SKF_AD_OFF + libc::SKF_AD_CPU) as u32;
1213+
flt[1].code = (libc::BPF_RET | 0x10) as u16;
1214+
let fp = libc::sock_fprog {
1215+
len: flt.len() as u16,
1216+
filter: flt.as_mut_ptr(),
1217+
};
1218+
setsockopt(&fd, sockopt::AttachReusePortCbpf, &fp).unwrap_or_else(|e| {
1219+
assert_eq!(e, nix::errno::Errno::ENOPROTOOPT);
1220+
});
1221+
}

0 commit comments

Comments
 (0)