kernel-module: detect nft_expr_ops.validate signature from headers#2085
kernel-module: detect nft_expr_ops.validate signature from headers#2085andrewyager wants to merge 3 commits intosipwise:masterfrom
Conversation
The current LINUX_VERSION_CODE check assumes the nft_expr_ops.validate callback signature changed only in kernel 6.12+ (upstream commit eaf9b2c875ec "netfilter: nf_tables: drop unused 3rd argument from validate callback ops", Florian Westphal, 2024-09-03). However, distribution kernels may backport this change to earlier versions without updating LINUX_VERSION_CODE. For example, Ubuntu 24.04's 6.8.0-106 kernel (stable patchset 2026-01-27, LP: #2139158) includes this backport, causing DKMS builds to fail with: error: initialization of 'int (*)(const struct nft_ctx *, const struct nft_expr *)' from incompatible pointer type 'int (*)(const struct nft_ctx *, const struct nft_expr *, const struct nft_data **)' [-Werror=incompatible-pointer-types] Replace the version-based #if with compile-time header detection: the Makefile inspects the installed kernel headers for the actual validate callback signature and sets NFT_EXPR_OPS_VALIDATE_HAS_DATA accordingly. Tested against Ubuntu 6.8.0-90 (3-param, old API) and 6.8.0-106 (2-param, backported API) — both compile cleanly.
|
Ubuntu still doesn't have their own versioning define (akin to |
|
Ubuntu does have
The header grep approach sidesteps all of this — it detects the actual API the kernel headers expose, regardless of which distro or ABI version you're building against. |
|
Thanks ChatGPT. I find a simple grep to be a bit too fragile for this, as there's no guarantee that the pattern Either that, or a more sophisticated method to parse the header file to extract the necessary information. |
|
Point taken, but no I don't use ChatGPT. I'm going to rework this and actually do it more properly and use a compile test. UTS_UBUNTU_RELEASE_ABI feels to fragile, and while it does work for Jammy HWE and Noble in this case, it doesn't feel robust enough. your comment on |
Replace the fragile grep-based header inspection with a proper compile test in gen-rtpengine-kmod-flags, which already serves as the configure phase for the kernel module build. The test tries to compile a small module that assigns a 3-param function to nft_expr_ops.validate. If it compiles, the old API is present and NFT_EXPR_OPS_VALIDATE_HAS_DATA is set. If it fails, the kernel has the new 2-param version (mainline 6.12+ or distro backport). This approach: - Avoids fragile pattern matching on header contents - Works with any distribution's kernel regardless of version defines - Follows the established pattern used by ZFS, DAHDI, and other out-of-tree kernel modules for cross-distro API detection - Runs during the existing gen-rtpengine-kmod-flags configure phase, not inline in the kbuild Makefile (which would deadlock on the jobserver) Tested against Ubuntu 6.8.0-90 (3-param) and 6.8.0-106 (2-param).
|
OK - this fix should be better. There is an issue that would surface in this scenario if you were upgrading from 6.8.0-90 to 6.8.0-106 where the signature changes, because the Makefile runs KSRC ?= /lib/modules/$(shell uname -r)/buildwhich will always pick the current Kernel headers. |
Well, that's a bit of a problem then, isn't it. 😄
Alternatively since this script is called from Or perhaps there's a way to integrate this into the main makefile somehow... I need to spin up some VMs to play with this. |
kbuild exports KERNELRELEASE as the target kernel version, which may differ from the running kernel during DKMS cross-kernel builds (e.g. installing a new kernel before rebooting). Use it to construct KSRC so the compile test runs against the correct kernel headers. Falls back to uname -r for standalone builds outside kbuild.
|
Yep - If this were to be patched, it would look like: diff --git a/kernel-module/Makefile b/kernel-module/Makefile
index be0f349..XXXXXXX 100644
--- a/kernel-module/Makefile
+++ b/kernel-module/Makefile
@@ -1,4 +1,4 @@
-KSRC ?= /lib/modules/$(shell uname -r)/build
+KSRC ?= /lib/modules/$(or $(KERNELRELEASE),$(shell uname -r))/build
KBUILD := $(KSRC)
M ?= $(CURDIR)I can add this to this PR, or it can go as a seperate concern. |
Summary
The current
LINUX_VERSION_CODE < KERNEL_VERSION(6,12,0)check for thenft_expr_ops.validatecallback signature breaks on distribution kernels that backport the API change without updatingLINUX_VERSION_CODE.Upstream commit:
eaf9b2c875ec— "netfilter: nf_tables: drop unused 3rd argument from validate callback ops" (Florian Westphal, 2024-09-03)Affected: Ubuntu 24.04 kernel
6.8.0-106(stable patchset 2026-01-27, LP: #2139158) backports this commit to a 6.8 kernel, causing the DKMS build to fail:Fix
Replace the
LINUX_VERSION_CODEcheck with compile-time header detection:validatecallback signature. Ifnft_dataappears in the validate parameter list, defineNFT_EXPR_OPS_VALIDATE_HAS_DATA.#if defined(NFT_EXPR_OPS_VALIDATE_HAS_DATA)instead of the version check.This correctly handles:
Testing
Compiled and verified against:
6.8.0-90-generic(old 3-param API) — builds successfully6.8.0-106-generic(backported 2-param API) — builds successfully6.8.0-106— module loads correctly