Skip to content

Commit 2429fb6

Browse files
authored
Split the UMEM fd out of SocketAddrXdp. (#1349)
Remove `SocketAddrXdp`'s shared umem field. Add a new `SocketAddrXdpWithSharedUmem` which pairs a `SocketAddrXdp` with a `BorrowedFd` for passing to `bind`. While here, rename `SockaddrXdpFlags` to `SocketAddrXdpFlags` for consistency with the other `SocketAddr*` types. This fixes the `SocketAddrXdp` side of #1001.
1 parent c7b2363 commit 2429fb6

4 files changed

Lines changed: 64 additions & 33 deletions

File tree

CHANGES.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,5 +245,14 @@ pointer provenance.
245245
[`rustix::io_uring::getevents_arg`]: https://docs.rs/rustix/1.0.0/rustix/io_uring/struct.io_uring_getevents_arg.html
246246
[`rustix::io_uring::io_uring_ptr`]: https://docs.rs/rustix/1.0.0-prerelease.0/rustix/io_uring/struct.io_uring_ptr.html
247247

248+
[`SocketAddrXdp`] no longer has a shared umem field. A new
249+
[`SocketAddrXdpWithSharedUmem`] is added for the purpose of calling `bind` and
250+
passing it an XDP address with a shared UMEM fd. And `SockaddrXdpFlags` is
251+
renamed to [`SocketAddrXdpFlags`].
252+
253+
[`SocketAddrXdp`]: https://docs.rs/rustix/1.0.0/rustix/net/xdp/struct.SocketAddrXdp.html
254+
[`SocketAddrXdpWithSharedUmem`]: https://docs.rs/rustix/1.0.0/rustix/net/xdp/struct.SocketAddrXdpWithSharedUmem.html
255+
[`SocketAddrXdpFlags`]: https://docs.rs/rustix/1.0.0/rustix/net/xdp/struct.SocketAddrXdpFlags.html
256+
248257
All explicitly deprecated functions and types have been removed. Their
249258
deprecation messages will have identified alternatives.

src/backend/libc/net/read_sockaddr.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::net::addr::SocketAddrLen;
1212
#[cfg(linux_kernel)]
1313
use crate::net::netlink::SocketAddrNetlink;
1414
#[cfg(target_os = "linux")]
15-
use crate::net::xdp::{SockaddrXdpFlags, SocketAddrXdp};
15+
use crate::net::xdp::{SocketAddrXdp, SocketAddrXdpFlags};
1616
use crate::net::{AddressFamily, Ipv4Addr, Ipv6Addr, SocketAddrAny, SocketAddrV4, SocketAddrV6};
1717
use core::mem::size_of;
1818

@@ -239,11 +239,14 @@ pub(crate) fn read_sockaddr_xdp(addr: &SocketAddrAny) -> Result<SocketAddrXdp, E
239239
}
240240
assert!(addr.addr_len() as usize >= size_of::<c::sockaddr_xdp>());
241241
let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_xdp>() };
242+
243+
// This ignores the `sxdp_shared_umem_fd` field, which is only expected to
244+
// be significant in `bind` calls, and not returned from `acceptfrom` or
245+
// `recvmsg` or similar.
242246
Ok(SocketAddrXdp::new(
243-
SockaddrXdpFlags::from_bits_retain(decode.sxdp_flags),
247+
SocketAddrXdpFlags::from_bits_retain(decode.sxdp_flags),
244248
u32::from_be(decode.sxdp_ifindex),
245249
u32::from_be(decode.sxdp_queue_id),
246-
u32::from_be(decode.sxdp_shared_umem_fd),
247250
))
248251
}
249252

src/backend/linux_raw/net/read_sockaddr.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::io::Errno;
77
use crate::net::addr::SocketAddrLen;
88
use crate::net::netlink::SocketAddrNetlink;
99
#[cfg(target_os = "linux")]
10-
use crate::net::xdp::{SockaddrXdpFlags, SocketAddrXdp};
10+
use crate::net::xdp::{SocketAddrXdp, SocketAddrXdpFlags};
1111
use crate::net::{
1212
AddressFamily, Ipv4Addr, Ipv6Addr, SocketAddrAny, SocketAddrUnix, SocketAddrV4, SocketAddrV6,
1313
};
@@ -133,11 +133,14 @@ pub(crate) fn read_sockaddr_xdp(addr: &SocketAddrAny) -> Result<SocketAddrXdp, E
133133
}
134134
assert!(addr.addr_len() as usize >= size_of::<c::sockaddr_xdp>());
135135
let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_xdp>() };
136+
137+
// This ignores the `sxdp_shared_umem_fd` field, which is only expected to
138+
// be significant in `bind` calls, and not returned from `acceptfrom` or
139+
// `recvmsg` or similar.
136140
Ok(SocketAddrXdp::new(
137-
SockaddrXdpFlags::from_bits_retain(decode.sxdp_flags),
141+
SocketAddrXdpFlags::from_bits_retain(decode.sxdp_flags),
138142
u32::from_be(decode.sxdp_ifindex),
139143
u32::from_be(decode.sxdp_queue_id),
140-
u32::from_be(decode.sxdp_shared_umem_fd),
141144
))
142145
}
143146

src/net/types.rs

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1620,6 +1620,7 @@ bitflags! {
16201620
#[cfg(target_os = "linux")]
16211621
pub mod xdp {
16221622
use crate::backend::net::read_sockaddr::read_sockaddr_xdp;
1623+
use crate::fd::{AsRawFd, BorrowedFd};
16231624
use crate::net::addr::{call_with_sockaddr, SocketAddrArg, SocketAddrLen, SocketAddrOpaque};
16241625
use crate::net::SocketAddrAny;
16251626

@@ -1644,7 +1645,7 @@ pub mod xdp {
16441645
/// `XDP_*` constants for use in [`SocketAddrXdp`].
16451646
#[repr(transparent)]
16461647
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
1647-
pub struct SockaddrXdpFlags: u16 {
1648+
pub struct SocketAddrXdpFlags: u16 {
16481649
/// `XDP_SHARED_UMEM`
16491650
const XDP_SHARED_UMEM = bitcast!(c::XDP_SHARED_UMEM as u16);
16501651
/// `XDP_COPY`
@@ -1683,46 +1684,40 @@ pub mod xdp {
16831684
///
16841685
/// Used to bind to XDP socket.
16851686
///
1686-
/// Not ABI compatible with `struct sockaddr_xdp`
1687+
/// Not ABI compatible with `struct sockaddr_xdp`.
1688+
///
1689+
/// To add a shared UMEM file descriptor, use [`SocketAddrXdpWithSharedUmem`].
16871690
// <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/if_xdp.h?h=v6.13#n48>
16881691
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
16891692
pub struct SocketAddrXdp {
16901693
/// Flags.
1691-
sxdp_flags: SockaddrXdpFlags,
1694+
sxdp_flags: SocketAddrXdpFlags,
16921695
/// Interface index.
16931696
sxdp_ifindex: u32,
16941697
/// Queue ID.
16951698
sxdp_queue_id: u32,
1696-
/// Shared UMEM file descriptor.
1697-
sxdp_shared_umem_fd: u32,
16981699
}
16991700

17001701
impl SocketAddrXdp {
17011702
/// Construct a new XDP address.
17021703
#[inline]
1703-
pub fn new(
1704-
flags: SockaddrXdpFlags,
1705-
interface_index: u32,
1706-
queue_id: u32,
1707-
share_umem_fd: u32,
1708-
) -> Self {
1704+
pub fn new(flags: SocketAddrXdpFlags, interface_index: u32, queue_id: u32) -> Self {
17091705
Self {
17101706
sxdp_flags: flags,
17111707
sxdp_ifindex: interface_index,
17121708
sxdp_queue_id: queue_id,
1713-
sxdp_shared_umem_fd: share_umem_fd,
17141709
}
17151710
}
17161711

17171712
/// Return flags.
17181713
#[inline]
1719-
pub fn flags(&self) -> SockaddrXdpFlags {
1714+
pub fn flags(&self) -> SocketAddrXdpFlags {
17201715
self.sxdp_flags
17211716
}
17221717

17231718
/// Set flags.
17241719
#[inline]
1725-
pub fn set_flags(&mut self, flags: SockaddrXdpFlags) {
1720+
pub fn set_flags(&mut self, flags: SocketAddrXdpFlags) {
17261721
self.sxdp_flags = flags;
17271722
}
17281723

@@ -1749,18 +1744,6 @@ pub mod xdp {
17491744
pub fn set_queue_id(&mut self, queue_id: u32) {
17501745
self.sxdp_queue_id = queue_id;
17511746
}
1752-
1753-
/// Return shared UMEM file descriptor.
1754-
#[inline]
1755-
pub fn shared_umem_fd(&self) -> u32 {
1756-
self.sxdp_shared_umem_fd
1757-
}
1758-
1759-
/// Set shared UMEM file descriptor.
1760-
#[inline]
1761-
pub fn set_shared_umem_fd(&mut self, shared_umem_fd: u32) {
1762-
self.sxdp_shared_umem_fd = shared_umem_fd;
1763-
}
17641747
}
17651748

17661749
#[allow(unsafe_code)]
@@ -1776,7 +1759,7 @@ pub mod xdp {
17761759
sxdp_flags: self.flags().bits(),
17771760
sxdp_ifindex: self.interface_index(),
17781761
sxdp_queue_id: self.queue_id(),
1779-
sxdp_shared_umem_fd: self.shared_umem_fd(),
1762+
sxdp_shared_umem_fd: !0,
17801763
};
17811764

17821765
call_with_sockaddr(&addr, f)
@@ -1798,6 +1781,39 @@ pub mod xdp {
17981781
}
17991782
}
18001783

1784+
/// An XDP socket address with a shared UMEM file descriptor.
1785+
///
1786+
/// This implements `SocketAddrArg` so that it can be passed to [`bind`].
1787+
///
1788+
/// [`bind`]: crate::net::bind
1789+
#[derive(Debug)]
1790+
pub struct SocketAddrXdpWithSharedUmem<'a> {
1791+
/// XDP address.
1792+
pub addr: SocketAddrXdp,
1793+
/// Shared UMEM file descriptor.
1794+
pub shared_umem_fd: BorrowedFd<'a>,
1795+
}
1796+
1797+
#[allow(unsafe_code)]
1798+
// SAFETY: `with_sockaddr` calls `f` using `call_with_sockaddr`, which
1799+
// handles calling `f` with the needed preconditions.
1800+
unsafe impl<'a> SocketAddrArg for SocketAddrXdpWithSharedUmem<'a> {
1801+
unsafe fn with_sockaddr<R>(
1802+
&self,
1803+
f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R,
1804+
) -> R {
1805+
let addr = c::sockaddr_xdp {
1806+
sxdp_family: c::AF_XDP as _,
1807+
sxdp_flags: self.addr.flags().bits(),
1808+
sxdp_ifindex: self.addr.interface_index(),
1809+
sxdp_queue_id: self.addr.queue_id(),
1810+
sxdp_shared_umem_fd: self.shared_umem_fd.as_raw_fd() as u32,
1811+
};
1812+
1813+
call_with_sockaddr(&addr, f)
1814+
}
1815+
}
1816+
18011817
/// XDP ring offset.
18021818
///
18031819
/// Used to mmap rings from kernel.

0 commit comments

Comments
 (0)