Skip to content

[0.2] if_tun.h ioctls for android #4392

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions libc-test/semver/android.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2897,13 +2897,42 @@ TIOCSWINSZ
TMPFS_MAGIC
TMP_MAX
TOSTOP
TUNATTACHFILTER
TUNDETACHFILTER
TUNGETFEATURES
TUNGETFILTER
TUNGETIFF
TUNGETSNDBUF
TUNGETVNETBE
TUNGETVNETHDRSZ
TUNGETVNETLE
TUNSETDEBUG
TUNSETFILTEREBPF
TUNSETGROUP
TUNSETIFF
TUNSETIFINDEX
TUNSETLINK
TUNSETNOCSUM
TUNSETOFFLOAD
TUNSETOWNER
TUNSETPERSIST
TUNSETQUEUE
TUNSETSNDBUF
TUNSETSTEERINGEBPF
TUNSETTXFILTER
TUNSETVNETBE
TUNSETVNETHDRSZ
TUNSETVNETLE
TUN_FLT_ALLMULTI
TUN_F_CSUM
TUN_F_TSO4
TUN_F_TSO6
TUN_F_TSO_ECN
TUN_F_UFO
TUN_F_USO4
TUN_F_USO6
TUN_PKT_STRIP
TUN_TX_TIMESTAMP
UINPUT_MAX_NAME_SIZE
UINPUT_VERSION
UIO_MAXIOV
Expand Down
55 changes: 55 additions & 0 deletions src/unix/linux_like/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2680,6 +2680,7 @@ pub const IFF_ATTACH_QUEUE: c_int = 0x0200;
pub const IFF_DETACH_QUEUE: c_int = 0x0400;
pub const IFF_PERSIST: c_int = 0x0800;
pub const IFF_NOFILTER: c_int = 0x1000;
pub const TUN_TX_TIMESTAMP: c_int = 1;
// Features for GSO (TUNSETOFFLOAD)
pub const TUN_F_CSUM: c_uint = 0x01;
pub const TUN_F_TSO4: c_uint = 0x02;
Expand All @@ -2688,6 +2689,40 @@ pub const TUN_F_TSO_ECN: c_uint = 0x08;
pub const TUN_F_UFO: c_uint = 0x10;
pub const TUN_F_USO4: c_uint = 0x20;
pub const TUN_F_USO6: c_uint = 0x40;
// Protocol info prepended to the packets (when IFF_NO_PI is not set)
pub const TUN_PKT_STRIP: c_int = 0x0001;
// Accept all multicast packets
pub const TUN_FLT_ALLMULTI: c_int = 0x0001;
// Ioctl operation codes
const T_TYPE: u32 = b'T' as u32;
pub const TUNSETNOCSUM: c_int = _IOW::<c_int>(T_TYPE, 200);
pub const TUNSETDEBUG: c_int = _IOW::<c_int>(T_TYPE, 201);
pub const TUNSETIFF: c_int = _IOW::<c_int>(T_TYPE, 202);
pub const TUNSETPERSIST: c_int = _IOW::<c_int>(T_TYPE, 203);
pub const TUNSETOWNER: c_int = _IOW::<c_int>(T_TYPE, 204);
pub const TUNSETLINK: c_int = _IOW::<c_int>(T_TYPE, 205);
pub const TUNSETGROUP: c_int = _IOW::<c_int>(T_TYPE, 206);
pub const TUNGETFEATURES: c_int = _IOR::<c_int>(T_TYPE, 207);
pub const TUNSETOFFLOAD: c_int = _IOW::<c_int>(T_TYPE, 208);
pub const TUNSETTXFILTER: c_int = _IOW::<c_int>(T_TYPE, 209);
pub const TUNGETIFF: c_int = _IOR::<c_int>(T_TYPE, 210);
pub const TUNGETSNDBUF: c_int = _IOR::<c_int>(T_TYPE, 211);
pub const TUNSETSNDBUF: c_int = _IOW::<c_int>(T_TYPE, 212);
pub const TUNATTACHFILTER: c_int = _IOW::<sock_fprog>(T_TYPE, 213);
pub const TUNDETACHFILTER: c_int = _IOW::<sock_fprog>(T_TYPE, 214);
pub const TUNGETVNETHDRSZ: c_int = _IOR::<c_int>(T_TYPE, 215);
pub const TUNSETVNETHDRSZ: c_int = _IOW::<c_int>(T_TYPE, 216);
pub const TUNSETQUEUE: c_int = _IOW::<c_int>(T_TYPE, 217);
pub const TUNSETIFINDEX: c_int = _IOW::<c_int>(T_TYPE, 218);
pub const TUNGETFILTER: c_int = _IOR::<sock_fprog>(T_TYPE, 219);
pub const TUNSETVNETLE: c_int = _IOW::<c_int>(T_TYPE, 220);
pub const TUNGETVNETLE: c_int = _IOR::<c_int>(T_TYPE, 221);
pub const TUNSETVNETBE: c_int = _IOW::<c_int>(T_TYPE, 222);
pub const TUNGETVNETBE: c_int = _IOR::<c_int>(T_TYPE, 223);
pub const TUNSETSTEERINGEBPF: c_int = _IOR::<c_int>(T_TYPE, 224);
pub const TUNSETFILTEREBPF: c_int = _IOR::<c_int>(T_TYPE, 225);
pub const TUNSETCARRIER: c_int = _IOW::<c_int>(T_TYPE, 226);
pub const TUNGETDEVNETNS: c_int = _IO(T_TYPE, 227);

// start android/platform/bionic/libc/kernel/uapi/linux/if_ether.h
// from https://android.googlesource.com/platform/bionic/+/HEAD/libc/kernel/uapi/linux/if_ether.h
Expand Down Expand Up @@ -4263,3 +4298,23 @@ impl siginfo_t {
self.sifields().sigchld.si_stime
}
}

/// Build an ioctl number for an argumentless ioctl.
pub const fn _IO(ty: u32, nr: u32) -> c_int {
super::_IOC(super::_IOC_NONE, ty, nr, 0) as c_int
}

/// Build an ioctl number for an read-only ioctl.
pub const fn _IOR<T>(ty: u32, nr: u32) -> c_int {
super::_IOC(super::_IOC_READ, ty, nr, mem::size_of::<T>()) as c_int
}

/// Build an ioctl number for an write-only ioctl.
pub const fn _IOW<T>(ty: u32, nr: u32) -> c_int {
super::_IOC(super::_IOC_WRITE, ty, nr, mem::size_of::<T>()) as c_int
}

/// Build an ioctl number for a read-write ioctl.
pub const fn _IOWR<T>(ty: u32, nr: u32) -> c_int {
super::_IOC(super::_IOC_READ | super::_IOC_WRITE, ty, nr, mem::size_of::<T>()) as c_int
}
68 changes: 4 additions & 64 deletions src/unix/linux_like/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5980,88 +5980,28 @@ pub const SCHED_FLAG_ALL: c_int = SCHED_FLAG_RESET_ON_FORK
pub const EPIOCSPARAMS: Ioctl = 0x40088a01;
pub const EPIOCGPARAMS: Ioctl = 0x80088a02;

const _IOC_NRBITS: u32 = 8;
const _IOC_TYPEBITS: u32 = 8;

// siginfo.h
pub const SI_DETHREAD: c_int = -7;
pub const TRAP_PERF: c_int = 6;

// https://github.com/search?q=repo%3Atorvalds%2Flinux+%22%23define+_IOC_NONE%22&type=code
cfg_if! {
if #[cfg(any(
any(target_arch = "powerpc", target_arch = "powerpc64"),
any(target_arch = "sparc", target_arch = "sparc64"),
any(target_arch = "mips", target_arch = "mips64"),
))] {
// https://github.com/torvalds/linux/blob/b311c1b497e51a628aa89e7cb954481e5f9dced2/arch/powerpc/include/uapi/asm/ioctl.h
// https://github.com/torvalds/linux/blob/b311c1b497e51a628aa89e7cb954481e5f9dced2/arch/sparc/include/uapi/asm/ioctl.h
// https://github.com/torvalds/linux/blob/b311c1b497e51a628aa89e7cb954481e5f9dced2/arch/mips/include/uapi/asm/ioctl.h

const _IOC_SIZEBITS: u32 = 13;
const _IOC_DIRBITS: u32 = 3;

const _IOC_NONE: u32 = 1;
const _IOC_READ: u32 = 2;
const _IOC_WRITE: u32 = 4;
} else {
// https://github.com/torvalds/linux/blob/b311c1b497e51a628aa89e7cb954481e5f9dced2/include/uapi/asm-generic/ioctl.h

const _IOC_SIZEBITS: u32 = 14;
const _IOC_DIRBITS: u32 = 2;

const _IOC_NONE: u32 = 0;
const _IOC_WRITE: u32 = 1;
const _IOC_READ: u32 = 2;
}
}

const _IOC_NRMASK: u32 = (1 << _IOC_NRBITS) - 1;
const _IOC_TYPEMASK: u32 = (1 << _IOC_TYPEBITS) - 1;
const _IOC_SIZEMASK: u32 = (1 << _IOC_SIZEBITS) - 1;
const _IOC_DIRMASK: u32 = (1 << _IOC_DIRBITS) - 1;

const _IOC_NRSHIFT: u32 = 0;
const _IOC_TYPESHIFT: u32 = _IOC_NRSHIFT + _IOC_NRBITS;
const _IOC_SIZESHIFT: u32 = _IOC_TYPESHIFT + _IOC_TYPEBITS;
const _IOC_DIRSHIFT: u32 = _IOC_SIZESHIFT + _IOC_SIZEBITS;

// adapted from https://github.com/torvalds/linux/blob/8a696a29c6905594e4abf78eaafcb62165ac61f1/rust/kernel/ioctl.rs

/// Build an ioctl number, analogous to the C macro of the same name.
const fn _IOC(dir: u32, ty: u32, nr: u32, size: usize) -> u32 {
// FIXME(ctest) the `garando_syntax` crate (used by ctest2 in the CI test suite)
// cannot currently parse these `debug_assert!`s
//
// debug_assert!(dir <= _IOC_DIRMASK);
// debug_assert!(ty <= _IOC_TYPEMASK);
// debug_assert!(nr <= _IOC_NRMASK);
// debug_assert!(size <= (_IOC_SIZEMASK as usize));

(dir << _IOC_DIRSHIFT)
| (ty << _IOC_TYPESHIFT)
| (nr << _IOC_NRSHIFT)
| ((size as u32) << _IOC_SIZESHIFT)
}

/// Build an ioctl number for an argumentless ioctl.
pub const fn _IO(ty: u32, nr: u32) -> u32 {
_IOC(_IOC_NONE, ty, nr, 0)
super::_IOC(super::_IOC_NONE, ty, nr, 0)
}

/// Build an ioctl number for an read-only ioctl.
pub const fn _IOR<T>(ty: u32, nr: u32) -> u32 {
_IOC(_IOC_READ, ty, nr, size_of::<T>())
super::_IOC(super::_IOC_READ, ty, nr, size_of::<T>())
}

/// Build an ioctl number for an write-only ioctl.
pub const fn _IOW<T>(ty: u32, nr: u32) -> u32 {
_IOC(_IOC_WRITE, ty, nr, size_of::<T>())
super::_IOC(super::_IOC_WRITE, ty, nr, size_of::<T>())
}

/// Build an ioctl number for a read-write ioctl.
pub const fn _IOWR<T>(ty: u32, nr: u32) -> u32 {
_IOC(_IOC_READ | _IOC_WRITE, ty, nr, size_of::<T>())
super::_IOC(super::_IOC_READ | super::_IOC_WRITE, ty, nr, size_of::<T>())
}

f! {
Expand Down
67 changes: 67 additions & 0 deletions src/unix/linux_like/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1631,6 +1631,73 @@ cfg_if! {
}
}

// https://github.com/search?q=repo%3Atorvalds%2Flinux+%22%23define+_IOC_NONE%22&type=code
cfg_if! {
if #[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "l4re"
))] {
const _IOC_NRBITS: u32 = 8;
const _IOC_TYPEBITS: u32 = 8;

cfg_if! {
if #[cfg(any(
any(target_arch = "powerpc", target_arch = "powerpc64"),
any(target_arch = "sparc", target_arch = "sparc64"),
any(target_arch = "mips", target_arch = "mips64"),
))] {
// https://github.com/torvalds/linux/blob/b311c1b497e51a628aa89e7cb954481e5f9dced2/arch/powerpc/include/uapi/asm/ioctl.h
// https://github.com/torvalds/linux/blob/b311c1b497e51a628aa89e7cb954481e5f9dced2/arch/sparc/include/uapi/asm/ioctl.h
// https://github.com/torvalds/linux/blob/b311c1b497e51a628aa89e7cb954481e5f9dced2/arch/mips/include/uapi/asm/ioctl.h

const _IOC_SIZEBITS: u32 = 13;
const _IOC_DIRBITS: u32 = 3;

const _IOC_NONE: u32 = 1;
const _IOC_READ: u32 = 2;
const _IOC_WRITE: u32 = 4;
} else {
// https://github.com/torvalds/linux/blob/b311c1b497e51a628aa89e7cb954481e5f9dced2/include/uapi/asm-generic/ioctl.h

const _IOC_SIZEBITS: u32 = 14;
const _IOC_DIRBITS: u32 = 2;

const _IOC_NONE: u32 = 0;
const _IOC_WRITE: u32 = 1;
const _IOC_READ: u32 = 2;
}
}
const _IOC_NRMASK: u32 = (1 << _IOC_NRBITS) - 1;
const _IOC_TYPEMASK: u32 = (1 << _IOC_TYPEBITS) - 1;
const _IOC_SIZEMASK: u32 = (1 << _IOC_SIZEBITS) - 1;
const _IOC_DIRMASK: u32 = (1 << _IOC_DIRBITS) - 1;

const _IOC_NRSHIFT: u32 = 0;
const _IOC_TYPESHIFT: u32 = _IOC_NRSHIFT + _IOC_NRBITS;
const _IOC_SIZESHIFT: u32 = _IOC_TYPESHIFT + _IOC_TYPEBITS;
const _IOC_DIRSHIFT: u32 = _IOC_SIZESHIFT + _IOC_SIZEBITS;

// adapted from https://github.com/torvalds/linux/blob/8a696a29c6905594e4abf78eaafcb62165ac61f1/rust/kernel/ioctl.rs

/// Build an ioctl number, analogous to the C macro of the same name.
const fn _IOC(dir: u32, ty: u32, nr: u32, size: usize) -> u32 {
// FIXME(ctest) the `garando_syntax` crate (used by ctest in the CI test suite)
// cannot currently parse these `debug_assert!`s
//
// debug_assert!(dir <= _IOC_DIRMASK);
// debug_assert!(ty <= _IOC_TYPEMASK);
// debug_assert!(nr <= _IOC_NRMASK);
// debug_assert!(size <= (_IOC_SIZEMASK as usize));

(dir << _IOC_DIRSHIFT)
| (ty << _IOC_TYPESHIFT)
| (nr << _IOC_NRSHIFT)
| ((size as u32) << _IOC_SIZESHIFT)
}
}
}

const_fn! {
{const} fn CMSG_ALIGN(len: usize) -> usize {
len + mem::size_of::<usize>() - 1 & !(mem::size_of::<usize>() - 1)
Expand Down