From eacbf7b4e7c147eb0a6986de8a616814e9ee5c91 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 25 Dec 2025 17:42:23 +0200 Subject: [PATCH 01/28] FreeBSD: add FreeBSD-specific build wrapper Signed-off-by: Konstantin Belousov --- build-freebsd.sh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100755 build-freebsd.sh diff --git a/build-freebsd.sh b/build-freebsd.sh new file mode 100755 index 000000000..a8389cde8 --- /dev/null +++ b/build-freebsd.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -e + +LOCALBASE=$(/sbin/sysctl -n user.localbase) +CMAKE=${LOCALBASE}/bin/cmake +NINJA=${LOCALBASE}/bin/ninja +PYTHON=${LOCALBASE}/bin/python3 +GCC=${LOCALBASE}/bin/gcc +GXX=${LOCALBASE}/bin/g++ + +SRCDIR=$(dirname $0) +BUILDDIR=${SRCDIR}/build + +mkdir -p ${BUILDDIR} + +cd ${BUILDDIR} + +${CMAKE} -DIN_PLACE=1 -GNinja -DENABLE_RESOLVE_NEIGH=0 -DIOCTL_MODE=write \ + -DPYTHON_EXECUTABLE=${PYTHON} \ + -DCMAKE_C_COMPILER=${GCC} -DCMAKE_CXX_COMPILER=${GXX} \ + ${EXTRA_CMAKE_FLAGS:-} .. +${NINJA} -k 0 From 34c926d9fda0ceb81953189cb46562b68f178cc4 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 9 Mar 2026 13:45:39 +0200 Subject: [PATCH 02/28] libibverbs/cmd_ioctl.h: fix typo in comment Signed-off-by: Konstantin Belousov --- libibverbs/cmd_ioctl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libibverbs/cmd_ioctl.h b/libibverbs/cmd_ioctl.h index 95fa7207c..b1e6446be 100644 --- a/libibverbs/cmd_ioctl.h +++ b/libibverbs/cmd_ioctl.h @@ -146,7 +146,7 @@ unsigned int __ioctl_final_num_attrs(unsigned int num_attrs, /* * C99 does not permit an initializer for VLAs, so this function does the init - * instead. It is called in the wonky way so that DELCARE_COMMAND_BUFFER can + * instead. It is called in the wonky way so that DECLARE_COMMAND_BUFFER can * still be a 'variable', and we so we don't require C11 mode. */ static inline int _ioctl_init_cmdb(struct ibv_command_buffer *cmd, From 323df825961a7fbb6fd7b51f98def2ac3915a3eb Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 5 Nov 2025 23:47:36 +0200 Subject: [PATCH 03/28] test version script: symbols are exported from the binary on FreeBSD Signed-off-by: Konstantin Belousov --- buildlib/FindLDSymVer.cmake | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/buildlib/FindLDSymVer.cmake b/buildlib/FindLDSymVer.cmake index d4065d922..154170053 100644 --- a/buildlib/FindLDSymVer.cmake +++ b/buildlib/FindLDSymVer.cmake @@ -3,12 +3,20 @@ # find_package helper to detect symbol version support in the compiler and # linker. If supported then LDSYMVER_MODE will be set to GNU +if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + set(GLOBAL_SYMBOLS_BIN " + environ; + __progname; + ") +endif() + # Basic sample GNU style map file file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test.map" " IBVERBS_1.0 { global: ibv_get_device_list; - local: *; + ${GLOBAL_SYMBOLS_BIN} + local: *; }; IBVERBS_1.1 { From 66cfc92907c42a8df862d7cc20aa45de15475701 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 5 Nov 2025 23:48:19 +0200 Subject: [PATCH 04/28] buildlib/rdma_functions.cmake: drop -T option from ln(1) invocation This seems to be unneeded Linuxism Signed-off-by: Konstantin Belousov --- buildlib/rdma_functions.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildlib/rdma_functions.cmake b/buildlib/rdma_functions.cmake index 6e0c7d2e8..097f27e18 100644 --- a/buildlib/rdma_functions.cmake +++ b/buildlib/rdma_functions.cmake @@ -57,7 +57,7 @@ function(rdma_create_symlink LINK_CONTENT DEST) # Newer versions of cmake can use "${CMAKE_COMMAND}" "-E" "create_symlink" # however it is broken weirdly on older versions. - execute_process(COMMAND "ln" "-Tsf" + execute_process(COMMAND "ln" "-sf" "${LINK_CONTENT}" "${DEST}" RESULT_VARIABLE retcode) if(NOT "${retcode}" STREQUAL "0") message(FATAL_ERROR "Failed to create symlink in ${DEST}") From b09d28a1fbcbcbe7ca11a6bcde237376beecb278 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 17 Feb 2026 14:57:59 +0200 Subject: [PATCH 05/28] buildlib/config.h.in: Make RDMA_CDEV_DIR right on FreeBSD Signed-off-by: Konstantin Belousov --- buildlib/config.h.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/buildlib/config.h.in b/buildlib/config.h.in index 0a7769e64..32c3acd27 100644 --- a/buildlib/config.h.in +++ b/buildlib/config.h.in @@ -13,7 +13,11 @@ // FIXME: Remove this, The cmake version hard-requires new style CLOEXEC support #define STREAM_CLOEXEC "e" +#if defined __linux__ #define RDMA_CDEV_DIR "/dev/infiniband" +#elif defined __FreeBSD__ +#define RDMA_CDEV_DIR "/dev" +#endif #define IBV_CONFIG_DIR "@CONFIG_DIR@" #define RS_CONF_DIR "@CMAKE_INSTALL_FULL_SYSCONFDIR@/rdma/rsocket" From 7c8652f37582c937a2a4f2c9cad1e6cd00b69c69 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 25 Dec 2025 17:34:10 +0200 Subject: [PATCH 06/28] CMakeLists.txt: netlink/netlink.h and netlink/route/route.h exist on FreeBSD Signed-off-by: Konstantin Belousov --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 06862ae58..6a256d959 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -564,13 +564,15 @@ else() set(NL_LIBRARIES "") RDMA_DoFixup(0 "netlink/attr.h") RDMA_DoFixup(0 "netlink/msg.h") - RDMA_DoFixup(0 "netlink/netlink.h") RDMA_DoFixup(0 "netlink/object-api.h") RDMA_DoFixup(0 "netlink/route/link.h") RDMA_DoFixup(0 "netlink/route/link/vlan.h") RDMA_DoFixup(0 "netlink/route/neighbour.h") - RDMA_DoFixup(0 "netlink/route/route.h") RDMA_DoFixup(0 "netlink/route/rtnl.h") + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + RDMA_DoFixup(0 "netlink/netlink.h") + RDMA_DoFixup(0 "netlink/route/route.h") + endif() endif() # Older stuff blows up if these headers are included together From 95407d38dffeba11e3360a3d9206ff7223287ebe Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 25 Dec 2025 18:16:29 +0200 Subject: [PATCH 07/28] librdmacm: on FreeBSD, epoll() is provided by epoll-shim Signed-off-by: Konstantin Belousov --- librdmacm/CMakeLists.txt | 8 ++++++++ librdmacm/examples/CMakeLists.txt | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/librdmacm/CMakeLists.txt b/librdmacm/CMakeLists.txt index e30626cd2..9bfd86fea 100644 --- a/librdmacm/CMakeLists.txt +++ b/librdmacm/CMakeLists.txt @@ -49,3 +49,11 @@ if (ENABLE_STATIC) endif() endif() rdma_pkg_config("rdmacm" "${REQUIRES}libibverbs" "${CMAKE_THREAD_LIBS_INIT}") + +if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + find_package(epoll-shim REQUIRED) + target_include_directories(rdmacm PRIVATE epoll-shim::epoll-shim) + target_link_libraries(rdmacm PRIVATE epoll-shim::epoll-shim) + target_include_directories(rspreload PRIVATE epoll-shim::epoll-shim) + target_link_libraries(rspreload PRIVATE epoll-shim::epoll-shim) +endif() diff --git a/librdmacm/examples/CMakeLists.txt b/librdmacm/examples/CMakeLists.txt index ed119466f..6f0a7ad1e 100644 --- a/librdmacm/examples/CMakeLists.txt +++ b/librdmacm/examples/CMakeLists.txt @@ -42,3 +42,27 @@ target_link_libraries(udaddy LINK_PRIVATE rdmacm rdmacm_tools) rdma_executable(udpong udpong.c) target_link_libraries(udpong LINK_PRIVATE rdmacm rdmacm_tools) + +if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + find_package(epoll-shim REQUIRED) + target_include_directories(rdmacm_tools PRIVATE epoll-shim::epoll-shim) + target_link_libraries(rdmacm_tools PRIVATE epoll-shim::epoll-shim) + target_include_directories(cmtime PRIVATE epoll-shim::epoll-shim) + target_link_libraries(cmtime PRIVATE epoll-shim::epoll-shim) + target_include_directories(mckey PRIVATE epoll-shim::epoll-shim) + target_link_libraries(mckey PRIVATE epoll-shim::epoll-shim) + target_include_directories(rcopy PRIVATE epoll-shim::epoll-shim) + target_link_libraries(rcopy PRIVATE epoll-shim::epoll-shim) + target_include_directories(riostream PRIVATE epoll-shim::epoll-shim) + target_link_libraries(riostream PRIVATE epoll-shim::epoll-shim) + target_include_directories(rping PRIVATE epoll-shim::epoll-shim) + target_link_libraries(rping PRIVATE epoll-shim::epoll-shim) + target_include_directories(rstream PRIVATE epoll-shim::epoll-shim) + target_link_libraries(rstream PRIVATE epoll-shim::epoll-shim) + target_include_directories(ucmatose PRIVATE epoll-shim::epoll-shim) + target_link_libraries(ucmatose PRIVATE epoll-shim::epoll-shim) + target_include_directories(udaddy PRIVATE epoll-shim::epoll-shim) + target_link_libraries(udaddy PRIVATE epoll-shim::epoll-shim) + target_include_directories(udpong PRIVATE epoll-shim::epoll-shim) + target_link_libraries(udpong PRIVATE epoll-shim::epoll-shim) +endif() From 52542fe7da7f3f677515e8de5d4a939c9a396923 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 24 Dec 2025 04:32:02 +0200 Subject: [PATCH 08/28] */*: AF_* come from sys/socket.h Signed-off-by: Konstantin Belousov --- infiniband-diags/ibaddr.c | 1 + infiniband-diags/ibdiag_common.c | 1 + infiniband-diags/saquery.c | 1 + libibmad/portid.c | 1 + libibmad/resolve.c | 1 + libibumad/tests/umad_sa_mcm_rereg_test.c | 1 + libibverbs/examples/devinfo.c | 1 + 7 files changed, 7 insertions(+) diff --git a/infiniband-diags/ibaddr.c b/infiniband-diags/ibaddr.c index c26492c09..af64ce410 100644 --- a/infiniband-diags/ibaddr.c +++ b/infiniband-diags/ibaddr.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include diff --git a/infiniband-diags/ibdiag_common.c b/infiniband-diags/ibdiag_common.c index 69b39480f..77687c1a5 100644 --- a/infiniband-diags/ibdiag_common.c +++ b/infiniband-diags/ibdiag_common.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include diff --git a/infiniband-diags/saquery.c b/infiniband-diags/saquery.c index 3d8c6ce08..70c99b73e 100644 --- a/infiniband-diags/saquery.c +++ b/infiniband-diags/saquery.c @@ -44,6 +44,7 @@ #include #include #include +#include #define _GNU_SOURCE diff --git a/libibmad/portid.c b/libibmad/portid.c index ea02ca9ae..b4572b228 100644 --- a/libibmad/portid.c +++ b/libibmad/portid.c @@ -35,6 +35,7 @@ #include #include #include +#include #include diff --git a/libibmad/resolve.c b/libibmad/resolve.c index 2c397eb1a..cbdf75272 100644 --- a/libibmad/resolve.c +++ b/libibmad/resolve.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/libibumad/tests/umad_sa_mcm_rereg_test.c b/libibumad/tests/umad_sa_mcm_rereg_test.c index 4330d9f14..64283509f 100644 --- a/libibumad/tests/umad_sa_mcm_rereg_test.c +++ b/libibumad/tests/umad_sa_mcm_rereg_test.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/libibverbs/examples/devinfo.c b/libibverbs/examples/devinfo.c index 1892ccd50..df561b60b 100644 --- a/libibverbs/examples/devinfo.c +++ b/libibverbs/examples/devinfo.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include From b9aa650da11ab386b88ae21e08f17848592b980a Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 24 Dec 2025 20:27:43 +0200 Subject: [PATCH 09/28] */*: add netinet/in.h and linux/ip6.h headers for struct sockaddr_in and struct in6_addr. Signed-off-by: Konstantin Belousov --- libibverbs/neigh.c | 1 + libibverbs/verbs.c | 1 + providers/rxe/rxe.h | 1 + providers/vmw_pvrdma/pvrdma.h | 2 ++ 4 files changed, 5 insertions(+) diff --git a/libibverbs/neigh.c b/libibverbs/neigh.c index 7eed95f14..464b8b8f0 100644 --- a/libibverbs/neigh.c +++ b/libibverbs/neigh.c @@ -9,6 +9,7 @@ #include #include +#include #if HAVE_WORKING_IF_H #include #endif diff --git a/libibverbs/verbs.c b/libibverbs/verbs.c index 0565be208..0a6bc56c5 100644 --- a/libibverbs/verbs.c +++ b/libibverbs/verbs.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include diff --git a/providers/rxe/rxe.h b/providers/rxe/rxe.h index 6da22b89f..241b866ea 100644 --- a/providers/rxe/rxe.h +++ b/providers/rxe/rxe.h @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "rxe-abi.h" diff --git a/providers/vmw_pvrdma/pvrdma.h b/providers/vmw_pvrdma/pvrdma.h index bb6ba729d..9c08dc8c4 100644 --- a/providers/vmw_pvrdma/pvrdma.h +++ b/providers/vmw_pvrdma/pvrdma.h @@ -54,6 +54,8 @@ #include #include #include +#include +#include #include #include #include From 4eb510da3441047988f00aaca9701ab0339d1e6f Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 25 Dec 2025 14:47:07 +0200 Subject: [PATCH 10/28] libibverbs/examples/xsrq_pingpong.c: needs sys/stat.h for S_IRUSR and friends Signed-off-by: Konstantin Belousov --- libibverbs/examples/xsrq_pingpong.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libibverbs/examples/xsrq_pingpong.c b/libibverbs/examples/xsrq_pingpong.c index c0dc0b2e1..ab89fd75b 100644 --- a/libibverbs/examples/xsrq_pingpong.c +++ b/libibverbs/examples/xsrq_pingpong.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include From 0e8c2f538278b7f806714c07c85050b156553040 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 25 Dec 2025 16:03:30 +0200 Subject: [PATCH 11/28] */*: avoid redefining ALIGN() macro On FreeBSD, the conflicting macro comes from sys/param.h. This is non-standard header, but it is needed for other target-specific headers. Just #undef system-provided ALIGN() before redefining the local one. Signed-off-by: Konstantin Belousov --- libibmad/mad.h | 1 + providers/mlx5/qp.c | 1 + 2 files changed, 2 insertions(+) diff --git a/libibmad/mad.h b/libibmad/mad.h index 99d3a5a06..8b527df3b 100644 --- a/libibmad/mad.h +++ b/libibmad/mad.h @@ -1714,6 +1714,7 @@ extern int ibdebug; /* Misc. macros: */ /** align value \a l to \a size (ceil) */ +#undef ALIGN #define ALIGN(l, size) (((l) + ((size) - 1)) / (size) * (size)) /** printf style warning MACRO, includes name of function and pid */ diff --git a/providers/mlx5/qp.c b/providers/mlx5/qp.c index b28273c83..4e72327b1 100644 --- a/providers/mlx5/qp.c +++ b/providers/mlx5/qp.c @@ -492,6 +492,7 @@ static inline int copy_eth_inline_headers(struct ibv_qp *ibqp, return 0; } +#undef ALIGN #define ALIGN(x, log_a) ((((x) + (1 << (log_a)) - 1)) & ~((1 << (log_a)) - 1)) static inline __be16 get_klm_octo(int nentries) From 5c88958dbd3b0112bb70a647fd5bf4bb8a183392 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 21 Jul 2026 23:48:56 +0300 Subject: [PATCH 12/28] librdmacm/preload.c: handle namespace polluition from the epoll-shim Signed-off-by: Konstantin Belousov --- librdmacm/preload.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/librdmacm/preload.c b/librdmacm/preload.c index f46e80f3a..51db3a59a 100644 --- a/librdmacm/preload.c +++ b/librdmacm/preload.c @@ -33,6 +33,10 @@ #define _GNU_SOURCE #include +#ifdef __FreeBSD__ +#define EPOLL_SHIM_DISABLE_WRAPPER_MACROS +#endif + #include #include #include From 4a9c51c6def7db7b0c87b1899f05848c41f8baea Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 26 Dec 2025 21:14:28 +0200 Subject: [PATCH 13/28] librdmacm/preload.c: account for differences in sendfile with FreeBSD Signed-off-by: Konstantin Belousov --- librdmacm/preload.c | 52 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/librdmacm/preload.c b/librdmacm/preload.c index 51db3a59a..1bc9d8c4f 100644 --- a/librdmacm/preload.c +++ b/librdmacm/preload.c @@ -35,6 +35,7 @@ #ifdef __FreeBSD__ #define EPOLL_SHIM_DISABLE_WRAPPER_MACROS +#include #endif #include @@ -73,6 +74,8 @@ ssize_t sendfile64(int out_fd, int in_fd, off64_t *offset64, size_t count); #endif #endif +struct sf_hdtr; + struct socket_calls { int (*socket)(int domain, int type, int protocol); int (*bind)(int socket, const struct sockaddr *addr, socklen_t addrlen); @@ -107,9 +110,14 @@ struct socket_calls { #endif int (*dup)(int oldfd); int (*dup2)(int oldfd, int newfd); +#if defined __linux__ ssize_t (*sendfile)(int out_fd, int in_fd, off_t *offset, size_t count); #if RDMA_PRELOAD_WRAP_LFS64 ssize_t (*sendfile64)(int out_fd, int in_fd, off64_t *offset64, size_t count); +#endif +#elif defined __FreeBSD__ + int (*sendfile)(int in_fd, int out_fd, off_t offset, size_t count, + struct sf_hdtr *hdtr, off_t *sbytes, int flags); #endif int (*fxstat)(int ver, int fd, struct stat *buf); }; @@ -1295,6 +1303,47 @@ int dup2(int oldfd, int newfd) return newfd; } +#if defined __FreeBSD__ +int sendfile(int in_fd, int out_fd, off_t offset, size_t count, + struct sf_hdtr *hdtr, off_t *sbytes, int flags) +{ + void *file_addr; + struct stat st; + int fd; + ssize_t ret; + off_t prev_offset; + uintptr_t file_addr_a; + + if (fd_get(out_fd, &fd) != fd_rsocket) { + return real.sendfile(in_fd, out_fd, offset, count, hdtr, + sbytes, flags); + } + if (hdtr != NULL || flags != 0) { + errno = EOPNOTSUPP; + return (-1); + } + if (count == 0) { + if (fstat(in_fd, &st) == -1) + return (-1); + count = st.st_size; + } + file_addr = mmap(NULL, round_page((offset & PAGE_MASK) + count), + PROT_READ, 0, in_fd, trunc_page(offset)); + if (file_addr == MAP_FAILED) + return -1; + file_addr_a = (uintptr_t)file_addr; + file_addr_a += offset & PAGE_MASK; /* GCC extension */ + prev_offset = lseek(in_fd, 0, SEEK_CUR); + ret = rwrite(fd, (void *)file_addr_a, count); + munmap(file_addr, count); + if (ret >= 0) { + if (sbytes != NULL) + *sbytes = ret; + lseek(in_fd, prev_offset, SEEK_SET); + } + return ret; +} +#elif defined __linux__ ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) { void *file_addr; @@ -1314,6 +1363,9 @@ ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) munmap(file_addr, count); return ret; } +#else +#error "Port me" +#endif #if RDMA_PRELOAD_WRAP_LFS64 ssize_t sendfile64(int out_fd, int in_fd, off64_t *offset64, size_t count) From c3eb970b1e38339cf9287016e9a5dd5bca77972e Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 26 Dec 2025 21:20:58 +0200 Subject: [PATCH 14/28] librdmacm/preload.c: switch init control to pthread_once Signed-off-by: Konstantin Belousov --- librdmacm/preload.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/librdmacm/preload.c b/librdmacm/preload.c index 1bc9d8c4f..079276cb8 100644 --- a/librdmacm/preload.c +++ b/librdmacm/preload.c @@ -403,18 +403,8 @@ static void getenv_options(void) fork_support = atoi(var); } -static void init_preload(void) +static void init_preload_act(void) { - static int init; - - /* Quick check without lock */ - if (init) - return; - - pthread_mutex_lock(&mut); - if (init) - goto out; - real.socket = dlsym(RTLD_NEXT, "socket"); real.bind = dlsym(RTLD_NEXT, "bind"); real.listen = dlsym(RTLD_NEXT, "listen"); @@ -476,9 +466,13 @@ static void init_preload(void) getenv_options(); scan_config(); - init = 1; -out: - pthread_mutex_unlock(&mut); +} + +static void init_preload(void) +{ + static pthread_once_t init_preload_ctrl = PTHREAD_ONCE_INIT; + + pthread_once(&init_preload_ctrl, init_preload_act); } /* From f88f18bdf0de66484426d1f04be22757355d8d60 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 26 Dec 2025 21:26:29 +0200 Subject: [PATCH 15/28] librdmacm/preload.c: provide program_invocation_short_name for FreeBSD Signed-off-by: Konstantin Belousov --- librdmacm/preload.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/librdmacm/preload.c b/librdmacm/preload.c index 079276cb8..6bb29bfdb 100644 --- a/librdmacm/preload.c +++ b/librdmacm/preload.c @@ -172,6 +172,13 @@ static void free_config(void) free(config); } +#ifdef __FreeBSD__ +#include + +static char program_invocation_short_name_buf[256]; +static char *program_invocation_short_name; +#endif + /* * Config file format: * # Starting '#' indicates comment @@ -466,6 +473,11 @@ static void init_preload_act(void) getenv_options(); scan_config(); +#ifdef __FreeBSD__ + strlcpy(program_invocation_short_name_buf, getprogname(), + sizeof(program_invocation_short_name_buf)); + program_invocation_short_name = basename(program_invocation_short_name_buf); +#endif } static void init_preload(void) From b583c84206a9f0dbfb51e44ff022cc3a8fe75f72 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 26 Dec 2025 21:28:59 +0200 Subject: [PATCH 16/28] librdmacm/preload.c: conditionalize handling of non-portable fcntls Signed-off-by: Konstantin Belousov --- librdmacm/preload.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/librdmacm/preload.c b/librdmacm/preload.c index 6bb29bfdb..640aaa677 100644 --- a/librdmacm/preload.c +++ b/librdmacm/preload.c @@ -1177,8 +1177,12 @@ int fcntl(int socket, int cmd, ... /* arg */) case F_GETFD: case F_GETFL: case F_GETOWN: +#ifdef F_GETSIG case F_GETSIG: +#endif +#ifdef F_GETLEASE case F_GETLEASE: +#endif ret = (fd_get(socket, &fd) == fd_rsocket) ? rfcntl(fd, cmd) : real.fcntl(fd, cmd); break; @@ -1187,9 +1191,15 @@ int fcntl(int socket, int cmd, ... /* arg */) case F_SETFD: case F_SETFL: case F_SETOWN: +#ifdef F_SETSIG case F_SETSIG: +#endif +#ifdef F_SETLEASE case F_SETLEASE: +#endif +#ifdef F_NOTIFY case F_NOTIFY: +#endif lparam = va_arg(args, long); ret = (fd_get(socket, &fd) == fd_rsocket) ? rfcntl(fd, cmd, lparam) : real.fcntl(fd, cmd, lparam); From ef278a8d6f815e897d30d5a8a4486bf5ccb27d30 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 3 Dec 2025 23:32:34 +0200 Subject: [PATCH 17/28] FreeBSD: add compat headers to mimic Linux build environment Signed-off-by: Konstantin Belousov --- CMakeLists.txt | 3 ++ freebsd-headers/CMakeLists.txt | 31 ++++++++++++++ freebsd-headers/alloca.h | 6 +++ freebsd-headers/errno.h | 10 +++++ freebsd-headers/limits.h | 10 +++++ freebsd-headers/linux/if_ether.h | 4 ++ freebsd-headers/linux/in.h | 4 ++ freebsd-headers/linux/in6.h | 25 ++++++++++++ freebsd-headers/linux/ioctl.h | 1 + freebsd-headers/linux/ip.h | 31 ++++++++++++++ freebsd-headers/linux/netlink.h | 7 ++++ freebsd-headers/linux/rtnetlink.h | 7 ++++ freebsd-headers/linux/socket.h | 4 ++ freebsd-headers/linux/stddef.h | 27 ++++++++++++ freebsd-headers/linux/types.h | 68 +++++++++++++++++++++++++++++++ freebsd-headers/netinet/in.h | 14 +++++++ freebsd-headers/netinet/tcp.h | 10 +++++ freebsd-headers/string.h | 35 ++++++++++++++++ freebsd-headers/sys/mman.h | 16 ++++++++ freebsd-headers/sys/sendfile.h | 8 ++++ freebsd-headers/sys/shm.h | 8 ++++ freebsd-headers/sys/socket.h | 7 ++++ freebsd-headers/sys/sysmacros.h | 6 +++ 23 files changed, 342 insertions(+) create mode 100644 freebsd-headers/CMakeLists.txt create mode 100644 freebsd-headers/alloca.h create mode 100644 freebsd-headers/errno.h create mode 100644 freebsd-headers/limits.h create mode 100644 freebsd-headers/linux/if_ether.h create mode 100644 freebsd-headers/linux/in.h create mode 100644 freebsd-headers/linux/in6.h create mode 100644 freebsd-headers/linux/ioctl.h create mode 100644 freebsd-headers/linux/ip.h create mode 100644 freebsd-headers/linux/netlink.h create mode 100644 freebsd-headers/linux/rtnetlink.h create mode 100644 freebsd-headers/linux/socket.h create mode 100644 freebsd-headers/linux/stddef.h create mode 100644 freebsd-headers/linux/types.h create mode 100644 freebsd-headers/netinet/in.h create mode 100644 freebsd-headers/netinet/tcp.h create mode 100644 freebsd-headers/string.h create mode 100644 freebsd-headers/sys/mman.h create mode 100644 freebsd-headers/sys/sendfile.h create mode 100644 freebsd-headers/sys/shm.h create mode 100644 freebsd-headers/sys/socket.h create mode 100644 freebsd-headers/sys/sysmacros.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a256d959..16d00e8c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -795,6 +795,9 @@ add_subdirectory(util/tests) add_subdirectory(Documentation) add_subdirectory(kernel-boot) add_subdirectory(kernel-headers) +if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + add_subdirectory(freebsd-headers) +endif() # Libraries add_subdirectory(libibumad) add_subdirectory(libibumad/man) diff --git a/freebsd-headers/CMakeLists.txt b/freebsd-headers/CMakeLists.txt new file mode 100644 index 000000000..1ff7c5fa2 --- /dev/null +++ b/freebsd-headers/CMakeLists.txt @@ -0,0 +1,31 @@ +publish_internal_headers("" + alloca.h + errno.h + limits.h + string.h + ) + +publish_internal_headers(netinet + netinet/in.h + netinet/tcp.h + ) + +publish_internal_headers(sys + sys/mman.h + sys/sendfile.h + sys/shm.h + sys/socket.h + sys/sysmacros.h + ) + +publish_internal_headers(linux + linux/if_ether.h + linux/in.h + linux/in6.h + linux/ioctl.h + linux/ip.h + linux/netlink.h + linux/rtnetlink.h + linux/socket.h + linux/types.h + ) diff --git a/freebsd-headers/alloca.h b/freebsd-headers/alloca.h new file mode 100644 index 000000000..69ddd74b3 --- /dev/null +++ b/freebsd-headers/alloca.h @@ -0,0 +1,6 @@ +#ifndef __FREEBSD_ALLOCA_H__ +#define __FREEBSD_ALLOCA_H__ + +/* empty */ + +#endif diff --git a/freebsd-headers/errno.h b/freebsd-headers/errno.h new file mode 100644 index 000000000..dfe0307e5 --- /dev/null +++ b/freebsd-headers/errno.h @@ -0,0 +1,10 @@ +#ifndef __FREEBSD_ERRNO_H__ +#define __FREEBSD_ERRNO_H__ + +#include_next +#define ENODATA 100000 +#define EBADE 100001 +#define EREMOTEIO 100002 +#define ENONET 100003 + +#endif diff --git a/freebsd-headers/limits.h b/freebsd-headers/limits.h new file mode 100644 index 000000000..f86942d9f --- /dev/null +++ b/freebsd-headers/limits.h @@ -0,0 +1,10 @@ +#ifndef __FREEBSD_LIMITS_H__ +#define __FREEBSD_LIMITS_H__ + +#include + +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX MAXHOSTNAMELEN +#endif + +#endif diff --git a/freebsd-headers/linux/if_ether.h b/freebsd-headers/linux/if_ether.h new file mode 100644 index 000000000..8cba917af --- /dev/null +++ b/freebsd-headers/linux/if_ether.h @@ -0,0 +1,4 @@ +#include + +#define ETH_ALEN ETHER_ADDR_LEN + diff --git a/freebsd-headers/linux/in.h b/freebsd-headers/linux/in.h new file mode 100644 index 000000000..b31116082 --- /dev/null +++ b/freebsd-headers/linux/in.h @@ -0,0 +1,4 @@ +#ifndef __FREEBSD_LINUX_IN_H__ +#define __FREEBSD_LINUX_IN_H__ + +#endif diff --git a/freebsd-headers/linux/in6.h b/freebsd-headers/linux/in6.h new file mode 100644 index 000000000..4a466b64b --- /dev/null +++ b/freebsd-headers/linux/in6.h @@ -0,0 +1,25 @@ +#ifndef __FREEBSD_LINUX_IN6_H__ +#define __FREEBSD_LINUX_IN6_H__ + +#include +#include + +struct linux_in6_addr { + union { + __u8 __u6_addr8[16]; + __be16 __u6_addr16[8]; + __be32 __u6_addr32[4]; + } __in6_u; +}; + +#undef s6_addr +#define s6_addr __in6_u.__u6_addr8 +#undef s6_addr16 +#define s6_addr16 __in6_u.__u6_addr16 +#undef s6_addr32 +#define s6_addr32 __in6_u.__u6_addr32 + +#define in6_addr linux_in6_addr +#define in6_u __in6_u + +#endif diff --git a/freebsd-headers/linux/ioctl.h b/freebsd-headers/linux/ioctl.h new file mode 100644 index 000000000..6ec92cf73 --- /dev/null +++ b/freebsd-headers/linux/ioctl.h @@ -0,0 +1 @@ +#include diff --git a/freebsd-headers/linux/ip.h b/freebsd-headers/linux/ip.h new file mode 100644 index 000000000..24de2e12c --- /dev/null +++ b/freebsd-headers/linux/ip.h @@ -0,0 +1,31 @@ +#ifndef __FREEBSD_LINUX_IP_H__ +#define __FREEBSD_LINUX_IP_H__ + +#include +#include +#include + +struct iphdr { +#if BYTE_ORDER == LITTLE_ENDIAN + __u8 ihl:4, + version:4; +#endif +#if BYTE_ORDER == BIG_ENDIAN + __u8 version:4, + ihl:4; +#endif + __u8 tos; + __be16 tot_len; + __be16 id; + __be16 frag_off; + __u8 ttl; + __u8 protocol; + __sum16 check; + __struct_group(/* no tag */, addrs, /* no attrs */, + __be32 saddr; + __be32 daddr; + ); + /*The options start here. */ +}; + +#endif diff --git a/freebsd-headers/linux/netlink.h b/freebsd-headers/linux/netlink.h new file mode 100644 index 000000000..256a194a2 --- /dev/null +++ b/freebsd-headers/linux/netlink.h @@ -0,0 +1,7 @@ +#ifndef __FREEBSD_LINUX_NETLINK_H +#define __FREEBSD_LINUX_NETLINK_H + +#include +#define NETLINK_RDMA 1000000 + +#endif diff --git a/freebsd-headers/linux/rtnetlink.h b/freebsd-headers/linux/rtnetlink.h new file mode 100644 index 000000000..1e456bb9d --- /dev/null +++ b/freebsd-headers/linux/rtnetlink.h @@ -0,0 +1,7 @@ +#ifndef __FREEBSD_LINUX_RTNETLINK_H__ +#define __FREEBSD_LINUX_RTNETLINK_H__ + +#include +#include + +#endif diff --git a/freebsd-headers/linux/socket.h b/freebsd-headers/linux/socket.h new file mode 100644 index 000000000..651d20c4b --- /dev/null +++ b/freebsd-headers/linux/socket.h @@ -0,0 +1,4 @@ +#ifndef __FREEBSD_LINUX_SOCKET_H__ +#define __FREEBSD_LINUX_SOCKET_H__ + +#endif diff --git a/freebsd-headers/linux/stddef.h b/freebsd-headers/linux/stddef.h new file mode 100644 index 000000000..95113a836 --- /dev/null +++ b/freebsd-headers/linux/stddef.h @@ -0,0 +1,27 @@ +#ifndef __FREEBSD_LINUX_STDDEF_H__ +#define __FREEBSD_LINUX_STDDEF_H__ + +#ifndef __cplusplus +#define __struct_group_tag(TAG) TAG +#else +#define __struct_group_tag(TAG) +#endif + +#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \ + union { \ + struct { MEMBERS } ATTRS; \ + struct __struct_group_tag(TAG) { MEMBERS } ATTRS NAME; \ + } ATTRS + +#ifdef __cplusplus +#define __DECLARE_FLEX_ARRAY(T, member) \ + T member[0] +#else +#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \ + struct { \ + struct { } __empty_ ## NAME; \ + TYPE NAME[]; \ + } +#endif + +#endif diff --git a/freebsd-headers/linux/types.h b/freebsd-headers/linux/types.h new file mode 100644 index 000000000..e3924c553 --- /dev/null +++ b/freebsd-headers/linux/types.h @@ -0,0 +1,68 @@ +/*- + * Copyright (c) 2010 Isilon Systems, Inc. + * Copyright (c) 2010 iX Systems, Inc. + * Copyright (c) 2010 Panasas, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _INFINIBAND_TYPES_H_ +#define _INFINIBAND_TYPES_H_ + +#include +#include + +//#define __bitwise __attribute__((bitwise)) +#define __bitwise + +typedef int8_t s8; +typedef uint8_t u8; +typedef int8_t __s8; +typedef uint8_t __u8; + +typedef int16_t s16; +typedef uint16_t u16; +typedef int16_t __s16; +typedef uint16_t __u16; +typedef __u16 __bitwise __sum16; + +typedef int32_t s32; +typedef uint32_t u32; +typedef int32_t __s32; +typedef uint32_t __u32; + +typedef int64_t s64; +typedef uint64_t u64; +typedef int64_t __s64; +typedef uint64_t __u64; + +typedef uint16_t __le16; +typedef uint16_t __be16; +typedef uint32_t __le32; +typedef uint32_t __be32; +typedef uint64_t __le64; +typedef uint64_t __be64; + +typedef uint64_t __aligned_u64; +typedef uint64_t __aligned_le64; + +#endif /* _INFINIBAND_TYPES_H_ */ diff --git a/freebsd-headers/netinet/in.h b/freebsd-headers/netinet/in.h new file mode 100644 index 000000000..0b0aec6b4 --- /dev/null +++ b/freebsd-headers/netinet/in.h @@ -0,0 +1,14 @@ +#ifndef __FREEBSD_NETINET_IN_H__ +#define __FREEBSD_NETINET_IN_H__ + +#include_next + +#undef IN6_IS_ADDR_V4MAPPED +#define IN6_IS_ADDR_V4MAPPED(a) \ + (__extension__ \ + ({ const struct in6_addr *__a = (const struct in6_addr *) (a); \ + __a->__in6_u.__u6_addr32[0] == 0 \ + && __a->__in6_u.__u6_addr32[1] == 0 \ + && __a->__in6_u.__u6_addr32[2] == htonl (0xffff); })) + +#endif diff --git a/freebsd-headers/netinet/tcp.h b/freebsd-headers/netinet/tcp.h new file mode 100644 index 000000000..f751f0488 --- /dev/null +++ b/freebsd-headers/netinet/tcp.h @@ -0,0 +1,10 @@ +#ifndef __FREEBSD_NETINET_TCP_H__ +#define __FREEBSD_NETINET_TCP_H__ + +#include_next +#include_next + +#define TCP_CLOSE TCPS_CLOSED +#define TCP_ESTABLISHED TCPS_ESTABLISHED + +#endif diff --git a/freebsd-headers/string.h b/freebsd-headers/string.h new file mode 100644 index 000000000..5226a805f --- /dev/null +++ b/freebsd-headers/string.h @@ -0,0 +1,35 @@ +#ifndef __FREEBSD_STRING_H__ +#define __FREEBSD_STRING_H__ + +#include_next + +#ifndef strdupa +#define strdupa(_Str) (__extension__({ \ + const char *_Str1; \ + size_t _Len; \ + char *_Copy; \ + \ + _Str1 = (_Str); \ + _Len = strlen(_Str1) + 1; \ + _Copy = (char *)__builtin_alloca(_Len); \ + memcpy(_Copy, _Str1, _Len); \ + _Copy; \ +})) +#endif + +#ifndef strndupa +#define strndupa(_Str, _Maxlen) (__extension__({ \ + const char *_Str1; \ + char *_Copy; \ + size_t _Len; \ + \ + _Str1 = (_Str); \ + _Len = strnlen((_Str1), (_Maxlen)); \ + _Copy = __builtin_alloca(_Len + 1); \ + (void)memcpy(_Copy, _Str1, _Len); \ + _Copy[_Len] = '\0'; \ + _Copy; \ +})) +#endif + +#endif diff --git a/freebsd-headers/sys/mman.h b/freebsd-headers/sys/mman.h new file mode 100644 index 000000000..601d21952 --- /dev/null +++ b/freebsd-headers/sys/mman.h @@ -0,0 +1,16 @@ +#ifndef __FREEBSD_SYS_MMAN_H__ +#define __FREEBSD_SYS_MMAN_H__ + +#include_next + +/* use minherit(2) as needed */ +#define MADV_DOFORK 0x10000001 +#define MADV_DONTFORK 0x10000002 + +#define MAP_LOCKED 0 /* XXXKIB implement ? */ +#define MAP_HUGETLB 0 +#define MAP_POPULATE 0 +#define MAP_NORESERVE 0 +#define MAP_GROWSDOWN 0 + +#endif diff --git a/freebsd-headers/sys/sendfile.h b/freebsd-headers/sys/sendfile.h new file mode 100644 index 000000000..ea1836b15 --- /dev/null +++ b/freebsd-headers/sys/sendfile.h @@ -0,0 +1,8 @@ +#ifndef __FREEBSD_SYS_SENDFILE_H__ +#define __FREEBSD_SYS_SENDFILE_H__ + +#include +#include +#include + +#endif diff --git a/freebsd-headers/sys/shm.h b/freebsd-headers/sys/shm.h new file mode 100644 index 000000000..4b3783f17 --- /dev/null +++ b/freebsd-headers/sys/shm.h @@ -0,0 +1,8 @@ +#ifndef __FREEBSD_SYS_SHM_H__ +#define __FREEBSD_SYS_SHM_H__ + +#include_next + +#define SHM_HUGETLB 0 + +#endif diff --git a/freebsd-headers/sys/socket.h b/freebsd-headers/sys/socket.h new file mode 100644 index 000000000..e644a0c2d --- /dev/null +++ b/freebsd-headers/sys/socket.h @@ -0,0 +1,7 @@ +#ifndef __FREEBSD_SYS_SOCKET_H__ +#define __FREEBSD_SYS_SOCKET_H__ + +#include_next +#define AF_LLC 1000000 + +#endif diff --git a/freebsd-headers/sys/sysmacros.h b/freebsd-headers/sys/sysmacros.h new file mode 100644 index 000000000..c30bcd62f --- /dev/null +++ b/freebsd-headers/sys/sysmacros.h @@ -0,0 +1,6 @@ +#ifndef __FREEBSD_SYS_SYSMACROS_H__ +#define __FREEBSD_SYS_SYSMACROS_H__ + +#include + +#endif From 51dac0dcea7cb822645b24a2eeabf3c3b58010cc Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 26 Dec 2025 21:48:14 +0200 Subject: [PATCH 18/28] madvise(MADV_*FORK) is spelled minherit(2) on FreeBSD Signed-off-by: Konstantin Belousov --- libibverbs/memory.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libibverbs/memory.c b/libibverbs/memory.c index c9821e664..d0c2f128f 100644 --- a/libibverbs/memory.c +++ b/libibverbs/memory.c @@ -605,7 +605,16 @@ static int do_madvise(void *addr, size_t length, int advice, int ret; void *p; +#if !defined INHERIT_COPY ret = madvise(addr, length, advice); +#else + if (advice == MADV_DOFORK || advice == MADV_DONTFORK) { + ret = minherit(addr, length, advice == MADV_DOFORK ? + INHERIT_COPY : INHERIT_NONE); + } else { + ret = madvise(addr, length, advice); + } +#endif if (!ret || advice == MADV_DONTFORK) return ret; @@ -614,8 +623,12 @@ static int do_madvise(void *addr, size_t length, int advice, /* if MADV_DOFORK failed we will try to remove VM_DONTCOPY * flag from each page */ +#if !defined INHERIT_COPY for (p = addr; p < addr + length; p += range_page_size) madvise(p, range_page_size, MADV_DOFORK); +#else + minherit(addr, length, INHERIT_COPY); +#endif } return 0; From 68c1a44aff2e9086a6f9fc44010af3f0260ab85b Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 28 Dec 2025 20:39:38 +0200 Subject: [PATCH 19/28] providers/rxe/rxe.c: use portable way to name ipv6 address field in sockaddr Signed-off-by: Konstantin Belousov --- providers/rxe/rxe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/rxe/rxe.c b/providers/rxe/rxe.c index 62615e65e..314f6739f 100644 --- a/providers/rxe/rxe.c +++ b/providers/rxe/rxe.c @@ -1738,7 +1738,7 @@ static inline int rdma_gid2ip(sockaddr_union_t *out, union ibv_gid *gid) } else { memset(&out->_sockaddr_in6, 0, sizeof(out->_sockaddr_in6)); out->_sockaddr_in6.sin6_family = AF_INET6; - memcpy(&out->_sockaddr_in6.sin6_addr.s6_addr, gid->raw, 16); + memcpy(&out->_sockaddr_in6.sin6_addr, gid->raw, 16); } return 0; } From 9576d008f513f1ae5c36ffe690c0d6c7748b7d96 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 27 Dec 2025 03:57:01 +0200 Subject: [PATCH 20/28] pyverbs/providers/mlx5/dr_action.pyx: fix type mismatch The actions[] argument to mlx5dv_dr_action_create_modify_header() is u64/uint64_t *. And on FreeBSD u64 is unsigned long, while on Linux it is unsigned long long. Both types have the same bit representation, but they are different in the C. Properly import types from linux/types.h, and add a placeholder to inform cython about __be64 existence with ctypedef (any integer type would work, according to the cython documentation). Signed-off-by: Konstantin Belousov --- pyverbs/providers/mlx5/dr_action.pyx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pyverbs/providers/mlx5/dr_action.pyx b/pyverbs/providers/mlx5/dr_action.pyx index 373c0e890..d60f9758b 100644 --- a/pyverbs/providers/mlx5/dr_action.pyx +++ b/pyverbs/providers/mlx5/dr_action.pyx @@ -9,7 +9,7 @@ from pyverbs.providers.mlx5.mlx5_enums import mlx5dv_dr_action_dest_type from pyverbs.pyverbs_error import PyverbsError from pyverbs.base cimport close_weakrefs from libc.stdlib cimport calloc, free -from libc.stdint cimport uint32_t, uint8_t +from libc.stdint cimport uint64_t, uint32_t, uint8_t from libc.string cimport memcpy import weakref import struct @@ -18,6 +18,8 @@ import errno be64toh = lambda num: struct.unpack('Q'.encode(), struct.pack('!8s'.encode(), num))[0] ACTION_SIZE = 8 +cdef extern from "": + ctypedef uint64_t __be64 cdef class DrAction(PyverbsCM): def __init__(self): @@ -111,7 +113,7 @@ cdef class DrActionModify(DrAction): """ super().__init__() action_buf_size = len(actions) * ACTION_SIZE - cdef unsigned long long *buf = calloc(1, action_buf_size) + cdef __be64 *buf = <__be64 *>calloc(1, action_buf_size) if buf == NULL: raise MemoryError('Failed to allocate memory', errno) From 4c99329ce4664343819f00a4db913c3c3afeb768 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 10 Jan 2026 14:08:21 +0200 Subject: [PATCH 21/28] libibverbs: Split Linux-specific initialization into dedicated source Signed-off-by: Konstantin Belousov --- libibverbs/CMakeLists.txt | 6 +- libibverbs/ibverbs.h | 1 + libibverbs/init-sysfs.c | 175 ++++++++++++++++++++++++++ libibverbs/init.c | 117 ----------------- libibverbs/{sysfs.c => sysfs-sysfs.c} | 0 5 files changed, 181 insertions(+), 118 deletions(-) create mode 100644 libibverbs/init-sysfs.c rename libibverbs/{sysfs.c => sysfs-sysfs.c} (100%) diff --git a/libibverbs/CMakeLists.txt b/libibverbs/CMakeLists.txt index 7fe44d861..567fad27c 100644 --- a/libibverbs/CMakeLists.txt +++ b/libibverbs/CMakeLists.txt @@ -20,6 +20,10 @@ publish_internal_headers(infiniband configure_file("libibverbs.map.in" "${CMAKE_CURRENT_BINARY_DIR}/libibverbs.map" @ONLY) +if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(SYSDEP_SOURCES init-sysfs.c sysfs-sysfs.c) +endif() + rdma_library(ibverbs "${CMAKE_CURRENT_BINARY_DIR}/libibverbs.map" # See Documentation/versioning.md 1 1.17.${PACKAGE_VERSION} @@ -56,8 +60,8 @@ rdma_library(ibverbs "${CMAKE_CURRENT_BINARY_DIR}/libibverbs.map" memory.c neigh.c static_driver.c - sysfs.c verbs.c + ${SYSDEP_SOURCES} ) target_link_libraries(ibverbs LINK_PRIVATE ${NL_LIBRARIES} diff --git a/libibverbs/ibverbs.h b/libibverbs/ibverbs.h index 33f83a7b9..2bb7b671d 100644 --- a/libibverbs/ibverbs.h +++ b/libibverbs/ibverbs.h @@ -90,6 +90,7 @@ static inline const struct verbs_context_ops *get_ops(struct ibv_context *ctx) enum ibv_node_type decode_knode_type(unsigned int knode_type); int find_sysfs_devs_nl(struct list_head *tmp_sysfs_dev_list); +int find_sysfs_devs(struct list_head *tmp_sysfs_dev_list); int try_access_device(const struct verbs_sysfs_dev *sysfs_dev); diff --git a/libibverbs/init-sysfs.c b/libibverbs/init-sysfs.c new file mode 100644 index 000000000..0ab1a0fca --- /dev/null +++ b/libibverbs/init-sysfs.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. + * Copyright (c) 2006 Cisco Systems, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#define _GNU_SOURCE +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "driver.h" +#include "ibverbs.h" +#include + +int setup_sysfs_uverbs(int uv_dirfd, const char *uverbs, + struct verbs_sysfs_dev *sysfs_dev) +{ + unsigned int major; + unsigned int minor; + struct stat buf; + char value[32]; + + if (!check_snprintf(sysfs_dev->sysfs_name, + sizeof(sysfs_dev->sysfs_name), "%s", uverbs)) + return -1; + + if (stat(sysfs_dev->ibdev_path, &buf)) + return -1; + sysfs_dev->time_created = buf.st_mtim; + + if (ibv_read_sysfs_file_at(uv_dirfd, "dev", value, + sizeof(value)) < 0) + return -1; + if (sscanf(value, "%u:%u", &major, &minor) != 2) + return -1; + sysfs_dev->sysfs_cdev = makedev(major, minor); + + if (ibv_read_sysfs_file_at(uv_dirfd, "abi_version", value, + sizeof(value)) > 0) + sysfs_dev->abi_ver = strtoul(value, NULL, 10); + + return 0; +} + +static int setup_sysfs_dev(int dirfd, const char *uverbs, + struct list_head *tmp_sysfs_dev_list) +{ + struct verbs_sysfs_dev *sysfs_dev = NULL; + char value[32]; + int uv_dirfd; + + sysfs_dev = calloc(1, sizeof(*sysfs_dev)); + if (!sysfs_dev) + return ENOMEM; + + sysfs_dev->ibdev_idx = -1; + + uv_dirfd = openat(dirfd, uverbs, O_RDONLY | O_DIRECTORY | O_CLOEXEC); + if (uv_dirfd == -1) + goto err_alloc; + + if (ibv_read_sysfs_file_at(uv_dirfd, "ibdev", sysfs_dev->ibdev_name, + sizeof(sysfs_dev->ibdev_name)) < 0) + goto err_fd; + + if (!check_snprintf( + sysfs_dev->ibdev_path, sizeof(sysfs_dev->ibdev_path), + "%s/class/infiniband/%s", ibv_get_sysfs_path(), + sysfs_dev->ibdev_name)) + goto err_fd; + + if (setup_sysfs_uverbs(uv_dirfd, uverbs, sysfs_dev)) + goto err_fd; + + if (ibv_read_ibdev_sysfs_file(value, sizeof(value), sysfs_dev, + "node_type") <= 0) + sysfs_dev->node_type = IBV_NODE_UNKNOWN; + else + sysfs_dev->node_type = + decode_knode_type(strtoul(value, NULL, 10)); + + if (try_access_device(sysfs_dev)) + goto err_fd; + + close(uv_dirfd); + list_add(tmp_sysfs_dev_list, &sysfs_dev->entry); + return 0; + +err_fd: + close(uv_dirfd); +err_alloc: + free(sysfs_dev); + return 0; +} + +int find_sysfs_devs(struct list_head *tmp_sysfs_dev_list) +{ + struct verbs_sysfs_dev *dev, *dev_tmp; + char class_path[IBV_SYSFS_PATH_MAX]; + DIR *class_dir; + struct dirent *dent; + int ret = 0; + + if (!check_snprintf(class_path, sizeof(class_path), + "%s/class/infiniband_verbs", ibv_get_sysfs_path())) + return ENOMEM; + + class_dir = opendir(class_path); + if (!class_dir) + return ENOSYS; + + while ((dent = readdir(class_dir))) { + if (dent->d_name[0] == '.') + continue; + + ret = setup_sysfs_dev(dirfd(class_dir), dent->d_name, + tmp_sysfs_dev_list); + if (ret) + break; + } + closedir(class_dir); + + if (ret) { + list_for_each_safe (tmp_sysfs_dev_list, dev, dev_tmp, entry) { + list_del(&dev->entry); + free(dev); + } + } + return ret; +} diff --git a/libibverbs/init.c b/libibverbs/init.c index 5f3d11e2d..fe271e95f 100644 --- a/libibverbs/init.c +++ b/libibverbs/init.c @@ -120,123 +120,6 @@ enum ibv_node_type decode_knode_type(unsigned int knode_type) return IBV_NODE_UNKNOWN; } -int setup_sysfs_uverbs(int uv_dirfd, const char *uverbs, - struct verbs_sysfs_dev *sysfs_dev) -{ - unsigned int major; - unsigned int minor; - struct stat buf; - char value[32]; - - if (!check_snprintf(sysfs_dev->sysfs_name, - sizeof(sysfs_dev->sysfs_name), "%s", uverbs)) - return -1; - - if (stat(sysfs_dev->ibdev_path, &buf)) - return -1; - sysfs_dev->time_created = buf.st_mtim; - - if (ibv_read_sysfs_file_at(uv_dirfd, "dev", value, - sizeof(value)) < 0) - return -1; - if (sscanf(value, "%u:%u", &major, &minor) != 2) - return -1; - sysfs_dev->sysfs_cdev = makedev(major, minor); - - if (ibv_read_sysfs_file_at(uv_dirfd, "abi_version", value, - sizeof(value)) > 0) - sysfs_dev->abi_ver = strtoul(value, NULL, 10); - - return 0; -} - -static int setup_sysfs_dev(int dirfd, const char *uverbs, - struct list_head *tmp_sysfs_dev_list) -{ - struct verbs_sysfs_dev *sysfs_dev = NULL; - char value[32]; - int uv_dirfd; - - sysfs_dev = calloc(1, sizeof(*sysfs_dev)); - if (!sysfs_dev) - return ENOMEM; - - sysfs_dev->ibdev_idx = -1; - - uv_dirfd = openat(dirfd, uverbs, O_RDONLY | O_DIRECTORY | O_CLOEXEC); - if (uv_dirfd == -1) - goto err_alloc; - - if (ibv_read_sysfs_file_at(uv_dirfd, "ibdev", sysfs_dev->ibdev_name, - sizeof(sysfs_dev->ibdev_name)) < 0) - goto err_fd; - - if (!check_snprintf( - sysfs_dev->ibdev_path, sizeof(sysfs_dev->ibdev_path), - "%s/class/infiniband/%s", ibv_get_sysfs_path(), - sysfs_dev->ibdev_name)) - goto err_fd; - - if (setup_sysfs_uverbs(uv_dirfd, uverbs, sysfs_dev)) - goto err_fd; - - if (ibv_read_ibdev_sysfs_file(value, sizeof(value), sysfs_dev, - "node_type") <= 0) - sysfs_dev->node_type = IBV_NODE_UNKNOWN; - else - sysfs_dev->node_type = - decode_knode_type(strtoul(value, NULL, 10)); - - if (try_access_device(sysfs_dev)) - goto err_fd; - - close(uv_dirfd); - list_add(tmp_sysfs_dev_list, &sysfs_dev->entry); - return 0; - -err_fd: - close(uv_dirfd); -err_alloc: - free(sysfs_dev); - return 0; -} - -static int find_sysfs_devs(struct list_head *tmp_sysfs_dev_list) -{ - struct verbs_sysfs_dev *dev, *dev_tmp; - char class_path[IBV_SYSFS_PATH_MAX]; - DIR *class_dir; - struct dirent *dent; - int ret = 0; - - if (!check_snprintf(class_path, sizeof(class_path), - "%s/class/infiniband_verbs", ibv_get_sysfs_path())) - return ENOMEM; - - class_dir = opendir(class_path); - if (!class_dir) - return ENOSYS; - - while ((dent = readdir(class_dir))) { - if (dent->d_name[0] == '.') - continue; - - ret = setup_sysfs_dev(dirfd(class_dir), dent->d_name, - tmp_sysfs_dev_list); - if (ret) - break; - } - closedir(class_dir); - - if (ret) { - list_for_each_safe (tmp_sysfs_dev_list, dev, dev_tmp, entry) { - list_del(&dev->entry); - free(dev); - } - } - return ret; -} - void verbs_register_driver(const struct verbs_device_ops *ops) { struct ibv_driver *driver; diff --git a/libibverbs/sysfs.c b/libibverbs/sysfs-sysfs.c similarity index 100% rename from libibverbs/sysfs.c rename to libibverbs/sysfs-sysfs.c From 5cb3a56a48f410c0caad2bedb099d309f41e5c10 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 19 Jan 2026 07:26:39 +0200 Subject: [PATCH 22/28] libibverbs: Add FreeBSD-specific implementation of init and sysfs access sysfs nodes are translated to sysctl MIBs same as it is done in the in-tree OFED port. Signed-off-by: Konstantin Belousov --- libibverbs/CMakeLists.txt | 4 ++ libibverbs/init-sysctl.c | 130 ++++++++++++++++++++++++++++++++++++++ libibverbs/sysfs-sysctl.c | 116 ++++++++++++++++++++++++++++++++++ 3 files changed, 250 insertions(+) create mode 100644 libibverbs/init-sysctl.c create mode 100644 libibverbs/sysfs-sysctl.c diff --git a/libibverbs/CMakeLists.txt b/libibverbs/CMakeLists.txt index 567fad27c..add477d2b 100644 --- a/libibverbs/CMakeLists.txt +++ b/libibverbs/CMakeLists.txt @@ -24,6 +24,10 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux") set(SYSDEP_SOURCES init-sysfs.c sysfs-sysfs.c) endif() +if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + set(SYSDEP_SOURCES init-sysctl.c sysfs-sysctl.c) +endif() + rdma_library(ibverbs "${CMAKE_CURRENT_BINARY_DIR}/libibverbs.map" # See Documentation/versioning.md 1 1.17.${PACKAGE_VERSION} diff --git a/libibverbs/init-sysctl.c b/libibverbs/init-sysctl.c new file mode 100644 index 000000000..8916914e5 --- /dev/null +++ b/libibverbs/init-sysctl.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. + * Copyright (c) 2006 Cisco Systems, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#define _GNU_SOURCE +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "driver.h" +#include "ibverbs.h" +#include + +int setup_sysfs_uverbs(int uv_dirfd, const char *uverbs, + struct verbs_sysfs_dev *sysfs_dev) +{ + return 0; +} + +int find_sysfs_devs(struct list_head *tmp_sysfs_dev_list) +{ + char class_path[IBV_SYSFS_PATH_MAX]; + char uverbs_path[IBV_SYSFS_PATH_MAX]; + struct verbs_sysfs_dev *sysfs_dev = NULL; + const char *sysfs_path; + char value[32]; + int i, ret; + + ret = 0; + sysfs_path = ibv_get_sysfs_path(); + + snprintf(class_path, sizeof class_path, "%s/class/infiniband_verbs", + sysfs_path); + + for (i = 0; i < 256; i++) { + if (sysfs_dev == NULL) { + sysfs_dev = calloc(1, sizeof *sysfs_dev); + if (sysfs_dev == NULL) { + ret = ENOMEM; + goto out; + } + } else { + memset(sysfs_dev, 0, sizeof(*sysfs_dev)); + } + + snprintf(sysfs_dev->sysfs_name, sizeof(sysfs_dev->sysfs_name), + "uverbs%d", i); + + snprintf(uverbs_path, sizeof(uverbs_path), + "%s/%s", class_path, sysfs_dev->sysfs_name); + + if (ibv_read_sysfs_file(uverbs_path, "ibdev", + sysfs_dev->ibdev_name, sizeof(sysfs_dev->ibdev_name)) < 0) + continue; + + if (!check_snprintf(sysfs_dev->ibdev_path, + sizeof(sysfs_dev->ibdev_path), "%s/class/infiniband/%s", + ibv_get_sysfs_path(), sysfs_dev->ibdev_name)) + continue; + + if (ibv_read_sysfs_file(uverbs_path, "abi_version", + value, sizeof(value)) > 0) + sysfs_dev->abi_ver = strtol(value, NULL, 10); + + if (ibv_read_sysfs_file(sysfs_dev->ibdev_path, "node_type", + value, sizeof(value)) > 0) { + sysfs_dev->node_type = + decode_knode_type(strtoul(value, NULL, 10)); + } else { + sysfs_dev->node_type = IBV_NODE_UNKNOWN; + } + // XXXKIB sysfs_dev->sysfs_cdev = XXX; + sysfs_dev->ibdev_idx = -1; + + list_add(tmp_sysfs_dev_list, &sysfs_dev->entry); + sysfs_dev = NULL; + } + + out: + if (sysfs_dev != NULL) + free(sysfs_dev); + + return ret; +} diff --git a/libibverbs/sysfs-sysctl.c b/libibverbs/sysfs-sysctl.c new file mode 100644 index 000000000..ff54414b1 --- /dev/null +++ b/libibverbs/sysfs-sysctl.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2006 Cisco Systems, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#define _GNU_SOURCE +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ibverbs.h" + +static const char *sysfs_path; + +const char *ibv_get_sysfs_path(void) +{ + const char *env = NULL; + static const char slash_sys[] = "/sys"; + + if (sysfs_path) + return sysfs_path; + + /* + * Only follow use path passed in through the calling user's + * environment if we're not running SUID. + */ + if (getuid() == geteuid()) + env = getenv("SYSFS_PATH"); + + if (env) { + int len; + char *dup; + + sysfs_path = dup = strndup(env, IBV_SYSFS_PATH_MAX); + if (dup == NULL) { + sysfs_path = slash_sys; + } else { + len = strlen(dup); + while (len > 0 && dup[len - 1] == '/') { + --len; + dup[len] = '\0'; + } + } + } else + sysfs_path = slash_sys; + + return sysfs_path; +} + +int ibv_read_sysfs_file(const char *dir, const char *file, + char *buf, size_t size) +{ + char *path, *s; + int ret; + size_t len; + + if (asprintf(&path, "%s/%s", dir, file) < 0) + return -1; + + for (s = &path[0]; *s != '\0'; s++) + if (*s == '/') + *s = '.'; + + len = size; + ret = sysctlbyname(&path[1], buf, &len, NULL, 0); + free(path); + + if (ret == -1) + return -1; + + if (len > 0 && buf[len - 1] == '\n') + buf[--len] = '\0'; + + return len; +} + +int ibv_read_ibdev_sysfs_file(char *buf, size_t size, + struct verbs_sysfs_dev *sysfs_dev, + const char *fnfmt, ...) +{ + /* XXXKIB */ + return -1; +} From a81239d0379d4cd5d4aad608c44af3bd9b40ea58 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 10 Feb 2026 08:54:32 +0200 Subject: [PATCH 23/28] libibverbs/sysfs-sysctl.c: hack for ibv_read_ibdev_sysfs_file("device/modalias") Construct pci vendor:devid string in Linux format. Signed-off-by: Konstantin Belousov --- libibverbs/sysfs-sysctl.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/libibverbs/sysfs-sysctl.c b/libibverbs/sysfs-sysctl.c index ff54414b1..99fe949a9 100644 --- a/libibverbs/sysfs-sysctl.c +++ b/libibverbs/sysfs-sysctl.c @@ -32,6 +32,7 @@ #define _GNU_SOURCE #include +#include #include #include #include @@ -111,6 +112,33 @@ int ibv_read_ibdev_sysfs_file(char *buf, size_t size, struct verbs_sysfs_dev *sysfs_dev, const char *fnfmt, ...) { - /* XXXKIB */ + char comp[IBV_SYSFS_PATH_MAX]; + va_list ap; + + va_start(ap, fnfmt); + vsnprintf(comp, sizeof(comp), fnfmt, ap); + va_end(ap); + + if (strcmp(comp, "device/modalias") == 0) { + char path_device[IBV_SYSFS_PATH_MAX]; + char value[64]; + unsigned vendor; + unsigned devid; + + snprintf(path_device, sizeof(path_device), "%s/%s/%s/device", + ibv_get_sysfs_path(), "class/infiniband_verbs", + sysfs_dev->sysfs_name); + if (ibv_read_sysfs_file(path_device, "vendor", value, + sizeof(value)) < 0) + return -1; + vendor = strtoul(value, NULL, 0); + if (ibv_read_sysfs_file(path_device, "device", value, + sizeof(value)) < 0) + return -1; + devid = strtoul(value, NULL, 0); + snprintf(buf, size, "pci:v%08Xd%08Xsv", vendor, devid); + return 1; + } + return -1; } From dbaf1e357be30b964a70d042294f25a41250d157 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 2 Feb 2026 03:57:24 +0200 Subject: [PATCH 24/28] FreeBSD: add IBVERBS_SYSCTL_VERBOSE Signed-off-by: Konstantin Belousov --- libibverbs/sysfs-sysctl.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/libibverbs/sysfs-sysctl.c b/libibverbs/sysfs-sysctl.c index 99fe949a9..83ab5c086 100644 --- a/libibverbs/sysfs-sysctl.c +++ b/libibverbs/sysfs-sysctl.c @@ -81,22 +81,40 @@ const char *ibv_get_sysfs_path(void) return sysfs_path; } +static int sysctl_verbose = -1; + int ibv_read_sysfs_file(const char *dir, const char *file, char *buf, size_t size) { - char *path, *s; + char *path, *s, *r; int ret; size_t len; + if (sysctl_verbose == -1) + sysctl_verbose = getenv("IBVERBS_SYSCTL_VERBOSE") != NULL; + if (asprintf(&path, "%s/%s", dir, file) < 0) return -1; + if (sysctl_verbose) + fprintf(stderr, "sysctl \"%s\": ", path); for (s = &path[0]; *s != '\0'; s++) if (*s == '/') *s = '.'; len = size; ret = sysctlbyname(&path[1], buf, &len, NULL, 0); + if (sysctl_verbose) { + if (ret == -1) { + fprintf(stderr, "error %d (%s)\n", errno, + strerror(errno)); + } else { + r = alloca(len + 1); + memcpy(r, buf, len); + r[len] = '\0'; + fprintf(stderr, "%s\n", r); + } + } free(path); if (ret == -1) From 983a01841918018d883e3684ab957c03bbe869bf Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 28 Dec 2025 23:17:52 +0200 Subject: [PATCH 25/28] Add README-FreeBSD.txt describing FreeBSD port requirements and the WIP. Signed-off-by: Konstantin Belousov --- README-FreeBSD.txt | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 README-FreeBSD.txt diff --git a/README-FreeBSD.txt b/README-FreeBSD.txt new file mode 100644 index 000000000..b85674c8f --- /dev/null +++ b/README-FreeBSD.txt @@ -0,0 +1,26 @@ +The port just compiles. + +FreeBSD version should be main or stable/15, after the tdestroy(3) and +strdupa()/strndupa() additions. + +You need to install the following packages: +cmake-core +ninja +gcc +python3 +pyXXX-cython3 +pyXXX-docutils +bash +libepoll-shim +pkgconf + +1. All fake constants for (rt)netlink that are added in + freebsd-headers/linux point to the usage areas that need porting. +2. sysfs accesses must be replaced by sysctl. + Similarly, there should be use of /proc that needs to be ported. +3. I have no idea if the FreeBSD verbs/drivers ABI is compatible with + the Linux provided by kernel-headers/*. +4. Tests for the compilation environment properties done in CMakeLists.txt + are performed before the freebsd-headers get chance to populate build + environment. As such, some tests provide invalid results, e.g. + the co-existence of netinet/in.h and linux/in*.h. From 6d95ab4bd9e0444c469afe9dcf06ba4190034fc8 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 3 Jun 2026 02:34:03 +0300 Subject: [PATCH 26/28] buildlib/make_abi_structs.py: allow #ifdef Allow to have #ifdef/#endif blocks inside the structure definition, using canonical system name in C preprocessor. Currently only __linux__ and __FreeBSD__ are recognized. Signed-off-by: Konstantin Belousov --- buildlib/make_abi_structs.py | 31 +++++++++++++++++++++++++++---- kernel-headers/CMakeLists.txt | 2 +- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/buildlib/make_abi_structs.py b/buildlib/make_abi_structs.py index 0817735eb..05b3d63c1 100644 --- a/buildlib/make_abi_structs.py +++ b/buildlib/make_abi_structs.py @@ -19,10 +19,33 @@ import re; import functools; import sys; +import os; -def in_struct(ln,FO,nesting=0): +sysname=sys.argv[3] + +def cpre_sysname(): + mapping = {"Linux": "__linux__", "FreeBSD": "__FreeBSD__"} + try: + return mapping[sysname] + except KeyError: + raise NotImplementedError(sysname) + +def in_struct(ln,FO,nesting=0,wait_for_endif=False,skip=False): """Copy a top level structure over to the #define output, keeping track of nested structures.""" + if wait_for_endif: + g = re.match(r"#endif", ln) + if g != None: + return functools.partial(in_struct,nesting=nesting,wait_for_endif=False,skip=False) + g = re.match(r"#ifdef\s+(\S+)",ln) + if g != None: + ifdefsym = g.group(1) + if ifdefsym == cpre_sysname(): + return functools.partial(in_struct,nesting=nesting,wait_for_endif=True,skip=False) + return functools.partial(in_struct,nesting=nesting,wait_for_endif=True,skip=True) + if skip: + return functools.partial(in_struct,nesting=nesting,wait_for_endif=wait_for_endif,skip=skip) + if nesting == 0: if re.match(r"(}.*);",ln): FO.write(ln[:-1] + "\n\n"); @@ -31,11 +54,11 @@ def in_struct(ln,FO,nesting=0): FO.write(ln + " \\\n"); if ln == "struct {" or ln == "union {": - return functools.partial(in_struct,nesting=nesting+1); + return functools.partial(in_struct,nesting=nesting+1,wait_for_endif=wait_for_endif,skip=skip); if re.match(r"}.*;",ln): - return functools.partial(in_struct,nesting=nesting-1); - return functools.partial(in_struct,nesting=nesting); + return functools.partial(in_struct,nesting=nesting-1,wait_for_endif=wait_for_endif,skip=skip); + return functools.partial(in_struct,nesting=nesting,wait_for_endif=wait_for_endif,skip=skip); def find_struct(ln,FO): """Look for the start of a top level structure""" diff --git a/kernel-headers/CMakeLists.txt b/kernel-headers/CMakeLists.txt index cd9c08cad..bcaee7b5d 100644 --- a/kernel-headers/CMakeLists.txt +++ b/kernel-headers/CMakeLists.txt @@ -51,7 +51,7 @@ function(rdma_kernel_provider_abi) set(HDRS ${HDRS} ${OHDR}) add_custom_command( OUTPUT "${OHDR}" - COMMAND "${PYTHON_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/buildlib/make_abi_structs.py" "${IHDR}" "${OHDR}" + COMMAND "${PYTHON_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/buildlib/make_abi_structs.py" "${IHDR}" "${OHDR}" "${CMAKE_SYSTEM_NAME}" MAIN_DEPENDENCY "${IHDR}" DEPENDS "${PROJECT_SOURCE_DIR}/buildlib/make_abi_structs.py" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" From 1090cdd96e4a4fc45401991c129b72db3eb6f5a1 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 3 Jun 2026 02:35:29 +0300 Subject: [PATCH 27/28] kernel-headers/rdma/mlx5-abi.h: provide FreeBSD layout for mlx5_ib_create_cq Signed-off-by: Konstantin Belousov --- kernel-headers/rdma/mlx5-abi.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/kernel-headers/rdma/mlx5-abi.h b/kernel-headers/rdma/mlx5-abi.h index 8a6ad6c68..904205a5b 100644 --- a/kernel-headers/rdma/mlx5-abi.h +++ b/kernel-headers/rdma/mlx5-abi.h @@ -287,6 +287,7 @@ enum mlx5_ib_create_cq_flags { }; struct mlx5_ib_create_cq { +#ifdef __linux__ __aligned_u64 buf_addr; __aligned_u64 db_addr; __u32 cqe_size; @@ -296,6 +297,18 @@ struct mlx5_ib_create_cq { __u16 uar_page_index; __u16 reserved0; __u32 reserved1; +#endif +#ifdef __FreeBSD__ + __u64 buf_addr; + __u64 db_addr; + __u32 cqe_size; + __u16 flags; + __u16 uar_page_index; + __u8 cqe_comp_en; + __u8 cqe_comp_res_format; + __u16 reserved0; + __u32 reserved1; +#endif }; struct mlx5_ib_create_cq_resp { From a207c6f321617466138358afd6ab6b95ce9a250f Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 13 Jul 2026 07:34:11 +0300 Subject: [PATCH 28/28] FreeBSD github ci workflow Signed-off-by: Konstantin Belousov --- .github/workflows/freebsd-ci.yml | 34 ++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/freebsd-ci.yml diff --git a/.github/workflows/freebsd-ci.yml b/.github/workflows/freebsd-ci.yml new file mode 100644 index 000000000..e097b9ed6 --- /dev/null +++ b/.github/workflows/freebsd-ci.yml @@ -0,0 +1,34 @@ +name: FreeBSD Build + +on: + push: + branches: [ "freebsd" ] + pull_request: + branches: [ "freebsd" ] + +jobs: + build-freebsd: + # vmactions runs a QEMU VM inside an Ubuntu runner, so runs-on MUST be ubuntu-latest + runs-on: ubuntu-latest + name: Build rdma-core on FreeBSD + + steps: + # Step 1: Check out your rdma-core repository into the Ubuntu host runner + - name: Checkout Code + uses: actions/checkout@v4 + + # Step 2: Fire up the FreeBSD VM and execute the build steps + - name: Build in FreeBSD VM + uses: vmactions/freebsd-vm@v1 + with: + release: "15.1" + usesh: true # Use standard sh rather than tcsh (default shell on FreeBSD) + + # The 'prepare' section runs inside the VM before copying files, + # ideal for installing system package dependencies. + prepare: | + uname -a + pkg install -y gcc cmake ninja python3 bash libepoll-shim pkgconf lang/cython + + run: | + bash build-freebsd.sh