libibmad: add per-port SA key configuration The libibmad SA query helpers have no way to supply a nonzero SM_Key. Calls through sa_rpc_call(), including ib_path_query_via() and ib_node_query_via(), therefore always issue untrusted requests with SM_Key 0. This prevents those helpers from querying records that require a trusted request, such as PKeyTableRecord, and from working with subnet managers configured to reject untrusted SA requests. Callers currently have to bypass the helpers and implement the UMAD transaction themselves. Add per-port sa_key_set() and sa_key_get() functions following the existing SMP M_Key API. Store the key in the opaque ibmad_port and copy it into rpc.mkey when constructing an SA request. Newly opened ports remain initialized to key 0, preserving existing behavior unless a caller explicitly sets a key. Export the new functions under IBMAD_1.6, update the libibmad ABI and distribution packaging, and document the API. Signed-off-by: Jonathan Süssemilch Poulain <jpoulain@coreweave.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt index be64e26..3ccd87f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -832,6 +832,7 @@ add_subdirectory(providers/siw) add_subdirectory(libibmad) +add_subdirectory(libibmad/man) add_subdirectory(libibnetdisc) add_subdirectory(libibnetdisc/man) add_subdirectory(infiniband-diags)
diff --git a/debian/libibmad-dev.install b/debian/libibmad-dev.install index 0083650..0150de4 100644 --- a/debian/libibmad-dev.install +++ b/debian/libibmad-dev.install
@@ -3,3 +3,5 @@ usr/lib/*/libibmad*.a usr/lib/*/libibmad*.so usr/lib/*/pkgconfig/libibmad.pc +usr/share/man/man3/sa_key_get.3 +usr/share/man/man3/sa_key_set.3
diff --git a/debian/libibmad5.symbols b/debian/libibmad5.symbols index 55460db..16d2c09 100644 --- a/debian/libibmad5.symbols +++ b/debian/libibmad5.symbols
@@ -3,6 +3,7 @@ IBMAD_1.3@IBMAD_1.3 1.3.11 IBMAD_1.4@IBMAD_1.4 54 IBMAD_1.5@IBMAD_1.5 56 + IBMAD_1.6@IBMAD_1.6 66 bm_call_via@IBMAD_1.3 1.3.11 cc_config_status_via@IBMAD_1.3 1.3.11 cc_query_status_via@IBMAD_1.3 1.3.11 @@ -160,3 +161,5 @@ xdump@IBMAD_1.3 1.3.11 mad_rpc_open_port2@IBMAD_1.5 56 mad_rpc_close_port2@IBMAD_1.5 56 + sa_key_get@IBMAD_1.6 66 + sa_key_set@IBMAD_1.6 66
diff --git a/libibmad/CMakeLists.txt b/libibmad/CMakeLists.txt index 27782f4..838ec45 100644 --- a/libibmad/CMakeLists.txt +++ b/libibmad/CMakeLists.txt
@@ -9,7 +9,7 @@ rdma_library(ibmad libibmad.map # See Documentation/versioning.md - 5 5.5.${PACKAGE_VERSION} + 5 5.6.${PACKAGE_VERSION} bm.c cc.c dump.c
diff --git a/libibmad/libibmad.map b/libibmad/libibmad.map index 7d150c0..4065ef4 100644 --- a/libibmad/libibmad.map +++ b/libibmad/libibmad.map
@@ -168,3 +168,8 @@ mad_rpc_close_port2; } IBMAD_1.4; +IBMAD_1.6 { + global: + sa_key_get; + sa_key_set; +} IBMAD_1.5;
diff --git a/libibmad/mad.h b/libibmad/mad.h index 99d3a5a..24d223e 100644 --- a/libibmad/mad.h +++ b/libibmad/mad.h
@@ -1612,6 +1612,8 @@ void *buf) __attribute__((deprecated)); /* sa.c new interface */ +void sa_key_set(struct ibmad_port *srcport, uint64_t key); +uint64_t sa_key_get(const struct ibmad_port *srcport); uint8_t *sa_rpc_call(const struct ibmad_port *srcport, void *rcvbuf, ib_portid_t *portid, ib_sa_call_t *sa, unsigned timeout); int ib_path_query_via(const struct ibmad_port *srcport, ibmad_gid_t srcgid,
diff --git a/libibmad/mad_internal.h b/libibmad/mad_internal.h index 5deac27..82314e7 100644 --- a/libibmad/mad_internal.h +++ b/libibmad/mad_internal.h
@@ -41,6 +41,7 @@ int class_agents[MAX_CLASS]; /* class2agent mapper */ int timeout, retries; uint64_t smp_mkey; + uint64_t sa_key; }; extern struct ibmad_port *ibmp;
diff --git a/libibmad/man/CMakeLists.txt b/libibmad/man/CMakeLists.txt new file mode 100644 index 0000000..8497d12 --- /dev/null +++ b/libibmad/man/CMakeLists.txt
@@ -0,0 +1,7 @@ +rdma_man_pages( + sa_key_set.3.md + ) + +rdma_alias_man_pages( + sa_key_set.3 sa_key_get.3 + )
diff --git a/libibmad/man/sa_key_set.3.md b/libibmad/man/sa_key_set.3.md new file mode 100644 index 0000000..159f731 --- /dev/null +++ b/libibmad/man/sa_key_set.3.md
@@ -0,0 +1,49 @@ +--- +date: 2026-09-24 +footer: libibmad +header: "Libibmad Programmer's Manual" +layout: page +license: 'Licensed under the OpenIB.org BSD license (FreeBSD Variant) - See COPYING.md' +section: 3 +title: SA_KEY_SET +--- + +# NAME + +sa_key_set, sa_key_get - set or get the SM_Key used for SA requests + +# SYNOPSIS + +```c +#include <infiniband/mad.h> + +void sa_key_set(struct ibmad_port *srcport, uint64_t key); + +uint64_t sa_key_get(const struct ibmad_port *srcport); +``` + +# DESCRIPTION + +**sa_key_set()** sets the Subnet Administration (SA) SM_Key associated with +*srcport*. Subsequent requests sent through **sa_rpc_call()**, including the +requests made by **ib_path_query_via()** and **ib_node_query_via()**, encode +*key* in the SM_Key field of the SA header. + +An **ibmad_port** returned by **mad_rpc_open_port()** or +**mad_rpc_open_port2()** initially has an SA SM_Key of 0. This preserves the +untrusted-request behavior used when **sa_key_set()** is not called. + +**sa_key_get()** returns the SA SM_Key currently associated with *srcport*. + +The SA SM_Key is separate from the SMP M_Key configured by +**smp_mkey_set()**. + +# RETURN VALUE + +**sa_key_set()** has no return value. + +**sa_key_get()** returns the configured SA SM_Key in host byte order. + +# AUTHORS + +Jonathan Süssemilch Poulain <jpoulain@coreweave.com>
diff --git a/libibmad/sa.c b/libibmad/sa.c index 9dfec93..d2675aa 100644 --- a/libibmad/sa.c +++ b/libibmad/sa.c
@@ -41,6 +41,16 @@ #undef DEBUG #define DEBUG if (ibdebug) IBWARN +void sa_key_set(struct ibmad_port *srcport, uint64_t key) +{ + srcport->sa_key = key; +} + +uint64_t sa_key_get(const struct ibmad_port *srcport) +{ + return srcport->sa_key; +} + uint8_t *sa_rpc_call(const struct ibmad_port *ibmad_port, void *rcvbuf, ib_portid_t * portid, ib_sa_call_t * sa, unsigned timeout) { @@ -64,6 +74,7 @@ rpc.datasz = IB_SA_DATA_SIZE; rpc.dataoffs = IB_SA_DATA_OFFS; rpc.trid = sa->trid; + rpc.mkey = ibmad_port->sa_key; portid->qp = 1; if (!portid->qkey)
diff --git a/redhat/rdma-core.spec b/redhat/rdma-core.spec index 461cd64..d0610fe 100644 --- a/redhat/rdma-core.spec +++ b/redhat/rdma-core.spec
@@ -470,6 +470,7 @@ %{_mandir}/man3/ibv_* %{_mandir}/man3/ionic_dv* %{_mandir}/man3/rdma* +%{_mandir}/man3/sa_key* %{_mandir}/man3/umad* %{_mandir}/man3/*_to_ibv_rate.* %{_mandir}/man7/rdma_cm.*
diff --git a/suse/rdma-core.spec b/suse/rdma-core.spec index 72eebd6..a694289 100644 --- a/suse/rdma-core.spec +++ b/suse/rdma-core.spec
@@ -678,6 +678,7 @@ %{_mandir}/man3/ibnd_* %{_mandir}/man3/ibv_* %{_mandir}/man3/rdma* +%{_mandir}/man3/sa_key* %{_mandir}/man3/umad* %{_mandir}/man3/*_to_ibv_rate.* %{_mandir}/man7/rdma_cm.*