Skip to content

Commit b561476

Browse files
authored
socket::sockopt AttachReusePortCbpf for Linux addition. (#2621)
Set a BPF program to the socket to set how packets are handled within the reuseport group.
1 parent 684b79e commit b561476

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

changelog/2621.added.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added `socket::sockopt::AttachReusePortCbpf` for Linux

src/sys/socket/sockopt.rs

+12
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,18 @@ sockopt_impl!(
12961296
libc::SO_EXCLBIND,
12971297
bool
12981298
);
1299+
#[cfg(target_os = "linux")]
1300+
sockopt_impl!(
1301+
/// To be used with `ReusePort`,
1302+
/// we can then attach a BPF (classic)
1303+
/// to set how the packets are assigned
1304+
/// to the socket (e.g. cpu distribution).
1305+
AttachReusePortCbpf,
1306+
SetOnly,
1307+
libc::SOL_SOCKET,
1308+
libc::SO_ATTACH_REUSEPORT_CBPF,
1309+
libc::sock_fprog
1310+
);
12991311

13001312
#[allow(missing_docs)]
13011313
// Not documented by Linux!

test/sys/test_sockopt.rs

+25
Original file line numberDiff line numberDiff line change
@@ -1249,3 +1249,28 @@ fn test_solfilter() {
12491249
assert_eq!(Err(Errno::ENOENT), setsockopt(&s, attach, data));
12501250
assert_eq!(Err(Errno::ENOENT), setsockopt(&s, detach, data));
12511251
}
1252+
1253+
#[cfg(target_os = "linux")]
1254+
#[test]
1255+
pub fn test_so_attach_reuseport_cbpf() {
1256+
let fd = socket(
1257+
AddressFamily::Inet6,
1258+
SockType::Datagram,
1259+
SockFlag::empty(),
1260+
None,
1261+
)
1262+
.unwrap();
1263+
setsockopt(&fd, sockopt::ReusePort, &true).unwrap();
1264+
setsockopt(&fd, sockopt::ReuseAddr, &true).unwrap();
1265+
let mut flt: [libc::sock_filter; 2] = unsafe { std::mem::zeroed() };
1266+
flt[0].code = (libc::BPF_LD | libc::BPF_W | libc::BPF_ABS) as u16;
1267+
flt[0].k = (libc::SKF_AD_OFF + libc::SKF_AD_CPU) as u32;
1268+
flt[1].code = (libc::BPF_RET | 0x10) as u16;
1269+
let fp = libc::sock_fprog {
1270+
len: flt.len() as u16,
1271+
filter: flt.as_mut_ptr(),
1272+
};
1273+
setsockopt(&fd, sockopt::AttachReusePortCbpf, &fp).unwrap_or_else(|e| {
1274+
assert_eq!(e, nix::errno::Errno::ENOPROTOOPT);
1275+
});
1276+
}

0 commit comments

Comments
 (0)