diff --git a/libc-test/Cargo.toml b/libc-test/Cargo.toml index bdeb5f503925..57324edf9e5e 100644 --- a/libc-test/Cargo.toml +++ b/libc-test/Cargo.toml @@ -32,6 +32,10 @@ extra_traits = ["libc/extra_traits"] name = "ctest" harness = false +[[test]] +name = "freebsd_netlink" +harness = false + [[test]] name = "linux_fcntl" harness = false diff --git a/libc-test/build/main.rs b/libc-test/build/main.rs index 3cf7aecf3dc4..1b0c3774803d 100755 --- a/libc-test/build/main.rs +++ b/libc-test/build/main.rs @@ -2455,6 +2455,94 @@ fn test_android(t: &Target) { } fn test_freebsd(t: &Target) { + // Ensures we have only one place where the `netlink/netlink.h` constants + // are checked in. This is used both when generating the full test suite, + // and when generating the `netlink`-specific test suite. + #[inline] + fn is_netlink_const(it: &ctest::Const) -> bool { + matches!( + it.ident(), + "CTRL_CMD_UNSPEC" + | "CTRL_CMD_NEWFAMILY" + | "CTRL_CMD_DELFAMILY" + | "CTRL_CMD_GETFAMILY" + | "CTRL_CMD_NEWOPS" + | "CTRL_CMD_DELOPS" + | "CTRL_CMD_GETOPS" + | "CTRL_CMD_NEWMCAST_GRP" + | "CTRL_CMD_DELMCAST_GRP" + | "CTRL_CMD_GETMCAST_GRP" + | "CTRL_CMD_GETPOLICY" + | "CTRL_ATTR_UNSPEC" + | "CTRL_ATTR_FAMILY_ID" + | "CTRL_ATTR_FAMILY_NAME" + | "CTRL_ATTR_VERSION" + | "CTRL_ATTR_HDRSIZE" + | "CTRL_ATTR_MAXATTR" + | "CTRL_ATTR_OPS" + | "CTRL_ATTR_MCAST_GROUPS" + | "CTRL_ATTR_POLICY" + | "CTRL_ATTR_OP_POLICY" + | "CTRL_ATTR_OP" + | "CTRL_ATTR_MCAST_GRP_UNSPEC" + | "CTRL_ATTR_MCAST_GRP_NAME" + | "CTRL_ATTR_MCAST_GRP_ID" + | "SOL_NETLINK" + | "NETLINK_ADD_MEMBERSHIP" + | "NETLINK_DROP_MEMBERSHIP" + | "NETLINK_PKTINFO" + | "NETLINK_BROADCAST_ERROR" + | "NETLINK_NO_ENOBUFS" + | "NETLINK_RX_RING" + | "NETLINK_TX_RING" + | "NETLINK_LISTEN_ALL_NSID" + | "NETLINK_LIST_MEMBERSHIPS" + | "NETLINK_CAP_ACK" + | "NETLINK_EXT_ACK" + | "NETLINK_GET_STRICT_CHK" + | "NLM_F_REQUEST" + | "NLM_F_MULTI" + | "NLM_F_ACK" + | "NLM_F_ECHO" + | "NLM_F_DUMP_INTR" + | "NLM_F_DUMP_FILTERED" + | "NLM_F_ROOT" + | "NLM_F_MATCH" + | "NLM_F_ATOMIC" + | "NLM_F_DUMP" + | "NLM_F_REPLACE" + | "NLM_F_EXCL" + | "NLM_F_CREATE" + | "NLM_F_APPEND" + | "NLM_F_NONREC" + | "NLM_F_CAPPED" + | "NLM_F_ACK_TLVS" + | "NLMSG_NOOP" + | "NLMSG_ERROR" + | "NLMSG_DONE" + | "NLMSG_OVERRUN" + | "NETLINK_ROUTE" + | "NETLINK_UNUSED" + | "NETLINK_USERSOCK" + | "NETLINK_FIREWALL" + | "NETLINK_SOCK_DIAG" + | "NETLINK_NFLOG" + | "NETLINK_XFRM" + | "NETLINK_SELINUX" + | "NETLINK_ISCSI" + | "NETLINK_AUDIT" + | "NETLINK_FIB_LOOKUP" + | "NETLINK_CONNECTOR" + | "NETLINK_NETFILTER" + | "NETLINK_IP6_FW" + | "NETLINK_DNRTMSG" + | "NETLINK_KOBJECT_UEVENT" + | "NETLINK_GENERIC" + | "NL_ITEM_ALIGN_SIZE" + | "NLMSG_ALIGNTO" + ) + } + assert!(t.freebsd()); let mut cfg = ctest_cfg(); @@ -2502,6 +2590,28 @@ fn test_freebsd(t: &Target) { let freebsd14 = matches!(freebsd_ver, Some(n) if n >= 14); let freebsd15 = matches!(freebsd_ver, Some(n) if n >= 15); + let mut netlink_cfg = cfg.clone(); + headers!(netlink_cfg, "netlink/netlink.h",); + netlink_cfg + .skip_struct(|ty| !matches!(ty.ident(), "sockaddr_nl")) + .skip_const(|c| !is_netlink_const(c)) + .skip_union(|_| true) + .skip_alias(|_| true) + .skip_static(|_| true) + .skip_fn(|_| true) + .skip_c_enum(|_| true); + ctest::generate_test(&mut netlink_cfg, "../src/lib.rs", "netlink_ctest_output.rs").unwrap(); + + // We must restore the above sure-skips because `TestGenerator` shares skips + // between cloned instances (here `cfg` and `netlink_cfg`.) + cfg.skip_struct(|_| false) + .skip_const(|_| false) + .skip_union(|_| false) + .skip_alias(|_| false) + .skip_static(|_| false) + .skip_fn(|_| false) + .skip_c_enum(|_| false); + headers!( cfg, "aio.h", @@ -2674,6 +2784,10 @@ fn test_freebsd(t: &Target) { cfg.skip_const(move |constant| { match constant.ident() { + // `netlink/netlink.h` constants. These are tests in a separate ctest + // invocation. + _ if is_netlink_const(constant) => true, + // These constants were introduced in FreeBSD 13: "F_ADD_SEALS" | "F_GET_SEALS" | "F_SEAL_SEAL" | "F_SEAL_SHRINK" | "F_SEAL_GROW" | "F_SEAL_WRITE" @@ -2959,6 +3073,10 @@ fn test_freebsd(t: &Target) { cfg.skip_struct(move |struct_| { match struct_.ident() { + // This is tested in a separate ctest invocation because some symbols + // `netlink/netlink.h` conflict with some other symbols from `net/if_mib.h`. + "sockaddr_nl" => true, + // `procstat` is a private struct "procstat" => true, diff --git a/libc-test/semver/freebsd.txt b/libc-test/semver/freebsd.txt index 037ee4c046ea..0b46638a282a 100644 --- a/libc-test/semver/freebsd.txt +++ b/libc-test/semver/freebsd.txt @@ -44,6 +44,7 @@ AF_LOCAL AF_NATM AF_NETBIOS AF_NETGRAPH +AF_NETLINK AF_OSI AF_PUP AF_ROUTE @@ -1024,6 +1025,7 @@ PF_LOCAL PF_NATM PF_NETBIOS PF_NETGRAPH +PF_NETLINK PF_OSI PF_PIP PF_PUP @@ -2173,6 +2175,84 @@ msgrcv msgsnd msqid_ds nallocx +netlink::NETLINK_ADD_MEMBERSHIP +netlink::NETLINK_AUDIT +netlink::NETLINK_BROADCAST_ERROR +netlink::NETLINK_CAP_ACK +netlink::NETLINK_CONNECTOR +netlink::NETLINK_DNRTMSG +netlink::NETLINK_DROP_MEMBERSHIP +netlink::NETLINK_EXT_ACK +netlink::NETLINK_FIB_LOOKUP +netlink::NETLINK_FIREWALL +netlink::NETLINK_GENERIC +netlink::NETLINK_GET_STRICT_CHK +netlink::NETLINK_IP6_FW +netlink::NETLINK_ISCSI +netlink::NETLINK_KOBJECT_UEVENT +netlink::NETLINK_LISTEN_ALL_NSID +netlink::NETLINK_LIST_MEMBERSHIPS +netlink::NETLINK_NETFILTER +netlink::NETLINK_NFLOG +netlink::NETLINK_NO_ENOBUFS +netlink::NETLINK_PKTINFO +netlink::NETLINK_ROUTE +netlink::NETLINK_RX_RING +netlink::NETLINK_SELINUX +netlink::NETLINK_SOCK_DIAG +netlink::NETLINK_TX_RING +netlink::NETLINK_UNUSED +netlink::NETLINK_USERSOCK +netlink::NETLINK_XFRM +netlink::NLMSG_ALIGNTO +netlink::NLMSG_DONE +netlink::NLMSG_ERROR +netlink::NLMSG_NOOP +netlink::NLMSG_OVERRUN +netlink::NLM_F_ACK +netlink::NLM_F_ACK_TLVS +netlink::NLM_F_APPEND +netlink::NLM_F_ATOMIC +netlink::NLM_F_CAPPED +netlink::NLM_F_CREATE +netlink::NLM_F_DUMP +netlink::NLM_F_DUMP_FILTERED +netlink::NLM_F_DUMP_INTR +netlink::NLM_F_ECHO +netlink::NLM_F_EXCL +netlink::NLM_F_MATCH +netlink::NLM_F_MULTI +netlink::NLM_F_NONREC +netlink::NLM_F_REPLACE +netlink::NLM_F_REQUEST +netlink::NLM_F_ROOT +netlink::NL_ITEM_ALIGN_SIZE +netlink::SOL_NETLINK +netlink_generic::CTRL_ATTR_FAMILY_ID +netlink_generic::CTRL_ATTR_FAMILY_NAME +netlink_generic::CTRL_ATTR_HDRSIZE +netlink_generic::CTRL_ATTR_MAXATTR +netlink_generic::CTRL_ATTR_MCAST_GROUPS +netlink_generic::CTRL_ATTR_MCAST_GRP_ID +netlink_generic::CTRL_ATTR_MCAST_GRP_NAME +netlink_generic::CTRL_ATTR_MCAST_GRP_UNSPEC +netlink_generic::CTRL_ATTR_OP +netlink_generic::CTRL_ATTR_OPS +netlink_generic::CTRL_ATTR_OP_POLICY +netlink_generic::CTRL_ATTR_POLICY +netlink_generic::CTRL_ATTR_UNSPEC +netlink_generic::CTRL_ATTR_VERSION +netlink_generic::CTRL_CMD_DELFAMILY +netlink_generic::CTRL_CMD_DELMCAST_GRP +netlink_generic::CTRL_CMD_DELOPS +netlink_generic::CTRL_CMD_GETFAMILY +netlink_generic::CTRL_CMD_GETMCAST_GRP +netlink_generic::CTRL_CMD_GETOPS +netlink_generic::CTRL_CMD_GETPOLICY +netlink_generic::CTRL_CMD_NEWFAMILY +netlink_generic::CTRL_CMD_NEWMCAST_GRP +netlink_generic::CTRL_CMD_NEWOPS +netlink_generic::CTRL_CMD_UNSPEC newlocale nice nl_item diff --git a/libc-test/tests/freebsd_netlink.rs b/libc-test/tests/freebsd_netlink.rs new file mode 100644 index 000000000000..50370d7b1faa --- /dev/null +++ b/libc-test/tests/freebsd_netlink.rs @@ -0,0 +1,17 @@ +#![allow(deprecated)] +#![allow(unused)] + +#[cfg(target_os = "freebsd")] +#[allow(unused_imports)] +use libc::{ + netlink::*, + netlink_generic::*, +}; + +#[cfg(target_os = "freebsd")] +include!(concat!(env!("OUT_DIR"), "/netlink_ctest_output.rs")); + +#[cfg(not(target_os = "freebsd"))] +fn main() { + println!("PASSED 0 tests"); +} diff --git a/src/new/freebsd/mod.rs b/src/new/freebsd/mod.rs index c0036c2a4e36..a8bfb036095c 100644 --- a/src/new/freebsd/mod.rs +++ b/src/new/freebsd/mod.rs @@ -5,5 +5,6 @@ pub(crate) mod net; pub(crate) mod netinet6; +pub mod netlink; pub(crate) mod sys; pub(crate) mod unistd; diff --git a/src/new/freebsd/netlink/mod.rs b/src/new/freebsd/netlink/mod.rs new file mode 100644 index 000000000000..1957137f4109 --- /dev/null +++ b/src/new/freebsd/netlink/mod.rs @@ -0,0 +1,6 @@ +//! Directory: `netlink/` +//! +//! + +pub mod netlink; +pub mod netlink_generic; diff --git a/src/new/freebsd/netlink/netlink.rs b/src/new/freebsd/netlink/netlink.rs new file mode 100644 index 000000000000..e02ef696aa00 --- /dev/null +++ b/src/new/freebsd/netlink/netlink.rs @@ -0,0 +1,77 @@ +//! Header: `netlink/netlink.h` +//! +//! + +use crate::prelude::*; + +s! { + pub struct sockaddr_nl { + pub nl_len: u8, + pub nl_family: crate::sa_family_t, + nl_pad: Padding, + pub nl_pid: u32, + pub nl_groups: u32, + } +} + +pub const SOL_NETLINK: c_int = 270; +pub const NETLINK_ADD_MEMBERSHIP: c_int = 1; +pub const NETLINK_DROP_MEMBERSHIP: c_int = 2; +pub const NETLINK_PKTINFO: c_int = 3; +pub const NETLINK_BROADCAST_ERROR: c_int = 4; +pub const NETLINK_NO_ENOBUFS: c_int = 5; +pub const NETLINK_RX_RING: c_int = 6; +pub const NETLINK_TX_RING: c_int = 7; +pub const NETLINK_LISTEN_ALL_NSID: c_int = 8; +pub const NETLINK_LIST_MEMBERSHIPS: c_int = 9; +pub const NETLINK_CAP_ACK: c_int = 10; +pub const NETLINK_EXT_ACK: c_int = 11; +pub const NETLINK_GET_STRICT_CHK: c_int = 12; + +pub const NLM_F_REQUEST: c_int = 0x01; +pub const NLM_F_MULTI: c_int = 0x02; +pub const NLM_F_ACK: c_int = 0x04; +pub const NLM_F_ECHO: c_int = 0x08; +pub const NLM_F_DUMP_INTR: c_int = 0x10; +pub const NLM_F_DUMP_FILTERED: c_int = 0x20; + +pub const NLM_F_ROOT: c_int = 0x100; +pub const NLM_F_MATCH: c_int = 0x200; +pub const NLM_F_ATOMIC: c_int = 0x400; +pub const NLM_F_DUMP: c_int = NLM_F_ROOT | NLM_F_MATCH; + +pub const NLM_F_REPLACE: c_int = 0x100; +pub const NLM_F_EXCL: c_int = 0x200; +pub const NLM_F_CREATE: c_int = 0x400; +pub const NLM_F_APPEND: c_int = 0x800; + +pub const NLM_F_NONREC: c_int = 0x100; + +pub const NLM_F_CAPPED: c_int = 0x100; +pub const NLM_F_ACK_TLVS: c_int = 0x200; + +pub const NLMSG_NOOP: c_int = 0x1; +pub const NLMSG_ERROR: c_int = 0x2; +pub const NLMSG_DONE: c_int = 0x3; +pub const NLMSG_OVERRUN: c_int = 0x4; + +pub const NETLINK_ROUTE: c_int = 0; +pub const NETLINK_UNUSED: c_int = 1; +pub const NETLINK_USERSOCK: c_int = 2; +pub const NETLINK_FIREWALL: c_int = 3; +pub const NETLINK_SOCK_DIAG: c_int = 4; +pub const NETLINK_NFLOG: c_int = 5; +pub const NETLINK_XFRM: c_int = 6; +pub const NETLINK_SELINUX: c_int = 7; +pub const NETLINK_ISCSI: c_int = 8; +pub const NETLINK_AUDIT: c_int = 9; +pub const NETLINK_FIB_LOOKUP: c_int = 10; +pub const NETLINK_CONNECTOR: c_int = 11; +pub const NETLINK_NETFILTER: c_int = 12; +pub const NETLINK_IP6_FW: c_int = 13; +pub const NETLINK_DNRTMSG: c_int = 14; +pub const NETLINK_KOBJECT_UEVENT: c_int = 15; +pub const NETLINK_GENERIC: c_int = 16; + +pub const NL_ITEM_ALIGN_SIZE: c_int = size_of::() as c_int; +pub const NLMSG_ALIGNTO: c_int = NL_ITEM_ALIGN_SIZE; diff --git a/src/new/freebsd/netlink/netlink_generic.rs b/src/new/freebsd/netlink/netlink_generic.rs new file mode 100644 index 000000000000..0bcb07b30567 --- /dev/null +++ b/src/new/freebsd/netlink/netlink_generic.rs @@ -0,0 +1,33 @@ +//! Header: `netlink/netlink_generic.h` +//! +//! + +use crate::prelude::*; + +pub const CTRL_CMD_UNSPEC: c_int = 0; +pub const CTRL_CMD_NEWFAMILY: c_int = 1; +pub const CTRL_CMD_DELFAMILY: c_int = 2; +pub const CTRL_CMD_GETFAMILY: c_int = 3; +pub const CTRL_CMD_NEWOPS: c_int = 4; +pub const CTRL_CMD_DELOPS: c_int = 5; +pub const CTRL_CMD_GETOPS: c_int = 6; +pub const CTRL_CMD_NEWMCAST_GRP: c_int = 7; +pub const CTRL_CMD_DELMCAST_GRP: c_int = 8; +pub const CTRL_CMD_GETMCAST_GRP: c_int = 9; +pub const CTRL_CMD_GETPOLICY: c_int = 10; + +pub const CTRL_ATTR_UNSPEC: c_int = 0; +pub const CTRL_ATTR_FAMILY_ID: c_int = 1; +pub const CTRL_ATTR_FAMILY_NAME: c_int = 2; +pub const CTRL_ATTR_VERSION: c_int = 3; +pub const CTRL_ATTR_HDRSIZE: c_int = 4; +pub const CTRL_ATTR_MAXATTR: c_int = 5; +pub const CTRL_ATTR_OPS: c_int = 6; +pub const CTRL_ATTR_MCAST_GROUPS: c_int = 7; +pub const CTRL_ATTR_POLICY: c_int = 8; +pub const CTRL_ATTR_OP_POLICY: c_int = 9; +pub const CTRL_ATTR_OP: c_int = 10; + +pub const CTRL_ATTR_MCAST_GRP_UNSPEC: c_int = 0; +pub const CTRL_ATTR_MCAST_GRP_NAME: c_int = 1; +pub const CTRL_ATTR_MCAST_GRP_ID: c_int = 2; diff --git a/src/new/freebsd/sys/socket.rs b/src/new/freebsd/sys/socket.rs index 8b3394f37c5d..1fe8560fd717 100644 --- a/src/new/freebsd/sys/socket.rs +++ b/src/new/freebsd/sys/socket.rs @@ -5,3 +5,6 @@ use crate::prelude::*; pub const SO_RERROR: c_int = 0x0002_0000; + +pub const AF_NETLINK: c_int = 38; +pub const PF_NETLINK: c_int = AF_NETLINK; diff --git a/src/new/mod.rs b/src/new/mod.rs index 3d1da7107b5e..59d66f960d05 100644 --- a/src/new/mod.rs +++ b/src/new/mod.rs @@ -65,7 +65,14 @@ cfg_if! { // pub(crate) use espidf::*; } else if #[cfg(target_os = "freebsd")] { mod freebsd; - pub(crate) use freebsd::*; + // FIXME(1.0,remove): should be part of the above reexport + pub use freebsd::netlink::*; + pub(crate) use freebsd::{ + net, + netinet6, + sys, + unistd, + }; } else if #[cfg(target_os = "fuchsia")] { mod fuchsia; pub(crate) use fuchsia::*;