Summary
The ovpn-dco kernel module (v0.2.20251017) fails to compile on CentOS Stream 9 with kernel 5.14.0-655.el9.x86_64 due to timer_container_of macro redefinition. This is caused by Red Hat's aggressive backporting of kernel 6.16+ timer APIs into the 5.14 kernel baseline, which the current DCO compatibility code does not detect.
Environment
Operating System:
NAME="CentOS Stream"
VERSION="9"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="9"
PLATFORM_ID="platform:el9"
CPE_NAME="cpe:/o:centos:centos:9"
Kernel Version:
uname -r
5.14.0-655.el9.x86_64
RHEL Release Code:
grep RHEL_RELEASE /usr/src/kernels/5.14.0-655.el9.x86_64/include/generated/uapi/linux/version.h
#define RHEL_RELEASE_VERSION(a,b) (((a) << 8) + (b))
#define RHEL_RELEASE_CODE 2312
#define RHEL_RELEASE "655"
Decoded: RHEL_RELEASE_CODE 2312 = RHEL 9.8 equivalent (9 << 8 + 8 = 2312)
DCO Version:
rpm -qa | grep ovpn-dco
kmod-ovpn-dco-0.2.20251017-2.el9.noarch
DCO Git Commit: Latest from October 17, 2025 (commit 5c595d5)
Build Error
Command
cd /usr/src/ovpn-dco-0.2.20251017.2.el9
make
Error Output
In file included from <command-line>:
/usr/src/ovpn-dco-0.2.20251017.2.el9/linux-compat.h:85: warning: "timer_container_of" redefined
85 | #define timer_container_of from_timer
|
In file included from ./include/linux/workqueue.h:9,
from ./include/linux/timer.h:139:
./include/linux/timer.h:139: note: this is the location of the previous definition
139 | #define timer_container_of(var, callback_timer, timer_fieldname) \
|
/usr/src/ovpn-dco-0.2.20251017.2.el9/drivers/net/ovpn-dco/peer.c: In function 'ovpn_peer_ping':
/usr/src/ovpn-dco-0.2.20251017.2.el9/linux-compat.h:85:28: error: implicit declaration of function 'from_timer'; did you mean 'mod_timer'? [-Werror=implicit-function-declaration]
85 | #define timer_container_of from_timer
| ^~~~~~~~~~
/usr/src/ovpn-dco-0.2.20251017.2.el9/drivers/net/ovpn-dco/peer.c:25:34: note: in expansion of macro 'timer_container_of'
25 | struct ovpn_peer *peer = timer_container_of(peer, t, keepalive_xmit);
| ^~~~~~~~~~~~~~~~~~
/usr/src/ovpn-dco-0.2.20251017.2.el9/drivers/net/ovpn-dco/peer.c:25:62: error: 'keepalive_xmit' undeclared (first use in this function)
25 | struct ovpn_peer *peer = timer_container_of(peer, t, keepalive_xmit);
| ^~~~~~~~~~~~~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:250: /usr/src/ovpn-dco-0.2.20251017.2.el9/drivers/net/ovpn-dco/peer.o] Error 1
Full error shows compilation fails in drivers/net/ovpn-dco/peer.c at lines 25 and 33 where timer_container_of is used.
Root Cause Analysis
The Aggressive Backporting Problem
Red Hat/CentOS Stream backports features from newer kernels into their 5.14 baseline while keeping the version number as "5.14". This breaks version-based feature detection.
Timeline of timer API changes:
- Kernel < 6.16: Uses
from_timer() function
- Kernel 6.16+: Uses
timer_container_of() macro
- CentOS Stream 5.14.0-655 (RHEL 9.8): Has
timer_container_of backported from 6.16+
Current DCO Compatibility Code
File: linux-compat.h (lines 76-108)
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 16, 0)
#ifndef UDP_ENCAP_OVPNINUDP
#define UDP_ENCAP_OVPNINUDP 100
#endif
#define timer_container_of from_timer // ← LINE 85: THE PROBLEM
enum ovpn_ifla_attrs {
// ...
};
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6, 16, 0) */
What happens:
- DCO checks:
LINUX_VERSION_CODE < KERNEL_VERSION(6, 16, 0)
- CentOS Stream kernel reports:
5.14.0-655 ✅ (passes check)
- DCO defines:
timer_container_of as alias to from_timer
- But kernel already has
timer_container_of (backported from 6.16+)
- Compiler error: macro redefinition + undefined
from_timer function
Missing RHEL Version Check
Unlike other compatibility fixes in the same file (lines 130, 140, 148, 156, 160), the timer_container_of block at line 76 does not check RHEL_RELEASE_CODE.
Examples of correct RHEL detection elsewhere in the code:
// Line 130: Correct pattern with RHEL check
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 12, 0) && \
RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(9, 6)
// ... compat code
#endif
// Line 160: Another correct pattern
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) && \
SUSE_PRODUCT_CODE < SUSE_PRODUCT(1, 15, 5, 0) && \
RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(9, 6)
// ... compat code
#endif
Evidence: RHEL Version Detection Works
CentOS Stream properly defines RHEL macros that DCO can use:
grep -r "RHEL_RELEASE" /usr/src/kernels/5.14.0-655.el9.x86_64/include/ | head -3
Output confirms:
#define RHEL_RELEASE_VERSION(a,b) (((a) << 8) + (b))
#define RHEL_RELEASE_CODE 2312
#define RHEL_RELEASE "655"
This means the fix is straightforward - add RHEL version detection like other compat blocks.
Comparison to Previous Similar Issues
This follows the exact same pattern as previously fixed RHEL backporting issues:
Issue #83: RHEL 9.6 Build Failure (Fixed May 2025)
- Kernel: 5.14.0-570.16.1.el9_6
- Error:
NETIF_F_LLTX undeclared, duplicate struct members
- Fix: Commit
ed8e85b added RHEL_RELEASE_VERSION(9, 6) checks
- Result: Fixed in v0.2.20250520
Issue #64: CentOS Stream 9 skb_gso_segment (Fixed May 2024)
- Kernel: 5.14.0-437.el9.x86_64
- Error: Backported
net/gso.h header
- Fix: Commit
c4c4f80 added RHEL-specific exception checks
- Result: Working in RHEL 9.4
Issue #74: CentOS Stream 9 Build Failure (Closed Feb 2025)
- Kernel: 5.14.0-536 through 5.14.0-547
- Error: Similar macro/struct conflicts
- Maintainer (ordex) confirmed: "Red Hat is backporting new features to older kernels and breaking version checks. This needs explicit fixing."
- User resolution: Migrated to CentOS Stream 10
Current Issue: timer_container_of (NEW - Unreported)
- Kernel: 5.14.0-655.el9.x86_64 (RHEL 9.8 equivalent)
- Error:
timer_container_of redefinition
- Cause: Backported timer API from kernel 6.16+
- Status: ❌ Not yet fixed
Verified Workaround ✅
Status: Successfully tested on CentOS Stream 9 with kernel 5.14.0-655.el9.x86_64
Users can manually patch the source code before building by adding RHEL version check to line 85:
cd /usr/src/ovpn-dco-0.2.20251017.2.el9
# Backup original file
cp linux-compat.h linux-compat.h.ORIGINAL
# Apply patch: wrap timer_container_of definition with RHEL version check
sed -i '85i\
/* Only define timer_container_of for kernels without the backport */\
#if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(9, 8)' linux-compat.h
sed -i '87a\
#endif' linux-compat.h
# Verify patch (should see nested #if for RHEL check)
sed -n '83,90p' linux-compat.h
# Build and install
make clean && make
make install
# Load module
modprobe -r ovpn-dco-v2
modprobe ovpn-dco-v2
# Verify module loaded
lsmod | grep ovpn
modinfo ovpn-dco-v2
# Restart OpenVPN
systemctl restart openvpnas
Results from testing:
# Successful build
Exit code: 0
-rw-r--r-- 1 root root 5.2M Feb 4 08:49 drivers/net/ovpn-dco/ovpn-dco-v2.ko
# Module loaded successfully
ovpn_dco_v2 98304 0
ip6_udp_tunnel 16384 1 ovpn_dco_v2
udp_tunnel 36864 1 ovpn_dco_v2
# OpenVPN Access Server working
● openvpnas.service - OpenVPN Access Server
Loaded: loaded (/usr/lib/systemd/system/openvpnas.service; enabled)
Active: active (running)
Patched code structure:
#endif
/* Only define timer_container_of for kernels without the backport */
#if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(9, 8)
#define timer_container_of from_timer
#endif
enum ovpn_ifla_attrs {
This workaround follows the same pattern used in other parts of the file (lines 130, 140, 148, 156, 160) and successfully prevents the macro redefinition error.
Related Commits
Timer API Compatibility (July 2025):
- Commit
98a25de: "ovpn-dco: compat hack for 6.15 timer_* API renaming"
- This fixed
timer_delete vs del_timer naming changes
- Did NOT address
timer_container_of for RHEL backports
6.16 Port (July 2025):
- Commit
b1b490e: "ovpn-dco: port to 6.16 and add compat hacks"
- Changed code from
from_timer() to timer_container_of()
- Added compat layer for kernels < 6.16
- Did NOT add RHEL version checks
Previous RHEL Fixes:
- Commit
5c595d5 (Oct 17, 2025): "fix 5.15 compat hack for RHEL9.6"
- Commit
ed8e85b (May 20, 2025): "add compat support for RHEL 9.6"
- Commit
2b17b01 (Jun 18, 2024): "fix gso.h compat code for RHEL 9.4"
Impact
Affected Systems:
- CentOS Stream 9 with kernel 5.14.0-655+
- RHEL 9.8+ (when released)
- Potentially RHEL 9.7 (needs verification)
Repository Information
Related Issues
Similar RHEL backporting issues previously fixed:
- #83 - RHEL 9.6 build failure
- #74 - CentOS Stream 9 build failure
- #64 - CentOS Stream 9 skb_gso_segment issue
Summary
The ovpn-dco kernel module (v0.2.20251017) fails to compile on CentOS Stream 9 with kernel 5.14.0-655.el9.x86_64 due to
timer_container_ofmacro redefinition. This is caused by Red Hat's aggressive backporting of kernel 6.16+ timer APIs into the 5.14 kernel baseline, which the current DCO compatibility code does not detect.Environment
Operating System:
Kernel Version:
RHEL Release Code:
Decoded: RHEL_RELEASE_CODE 2312 = RHEL 9.8 equivalent (9 << 8 + 8 = 2312)
DCO Version:
rpm -qa | grep ovpn-dco kmod-ovpn-dco-0.2.20251017-2.el9.noarchDCO Git Commit: Latest from October 17, 2025 (commit
5c595d5)Build Error
Command
cd /usr/src/ovpn-dco-0.2.20251017.2.el9 makeError Output
Full error shows compilation fails in
drivers/net/ovpn-dco/peer.cat lines 25 and 33 wheretimer_container_ofis used.Root Cause Analysis
The Aggressive Backporting Problem
Red Hat/CentOS Stream backports features from newer kernels into their 5.14 baseline while keeping the version number as "5.14". This breaks version-based feature detection.
Timeline of timer API changes:
from_timer()functiontimer_container_of()macrotimer_container_ofbackported from 6.16+Current DCO Compatibility Code
File:
linux-compat.h(lines 76-108)What happens:
LINUX_VERSION_CODE < KERNEL_VERSION(6, 16, 0)5.14.0-655✅ (passes check)timer_container_ofas alias tofrom_timertimer_container_of(backported from 6.16+)from_timerfunctionMissing RHEL Version Check
Unlike other compatibility fixes in the same file (lines 130, 140, 148, 156, 160), the
timer_container_ofblock at line 76 does not check RHEL_RELEASE_CODE.Examples of correct RHEL detection elsewhere in the code:
Evidence: RHEL Version Detection Works
CentOS Stream properly defines RHEL macros that DCO can use:
Output confirms:
This means the fix is straightforward - add RHEL version detection like other compat blocks.
Comparison to Previous Similar Issues
This follows the exact same pattern as previously fixed RHEL backporting issues:
Issue #83: RHEL 9.6 Build Failure (Fixed May 2025)
NETIF_F_LLTXundeclared, duplicate struct membersed8e85baddedRHEL_RELEASE_VERSION(9, 6)checksIssue #64: CentOS Stream 9
skb_gso_segment(Fixed May 2024)net/gso.hheaderc4c4f80added RHEL-specific exception checksIssue #74: CentOS Stream 9 Build Failure (Closed Feb 2025)
Current Issue: timer_container_of (NEW - Unreported)
timer_container_ofredefinitionVerified Workaround ✅
Status: Successfully tested on CentOS Stream 9 with kernel 5.14.0-655.el9.x86_64
Users can manually patch the source code before building by adding RHEL version check to line 85:
Results from testing:
Patched code structure:
This workaround follows the same pattern used in other parts of the file (lines 130, 140, 148, 156, 160) and successfully prevents the macro redefinition error.
Related Commits
Timer API Compatibility (July 2025):
98a25de: "ovpn-dco: compat hack for 6.15 timer_* API renaming"timer_deletevsdel_timernaming changestimer_container_offor RHEL backports6.16 Port (July 2025):
b1b490e: "ovpn-dco: port to 6.16 and add compat hacks"from_timer()totimer_container_of()Previous RHEL Fixes:
5c595d5(Oct 17, 2025): "fix 5.15 compat hack for RHEL9.6"ed8e85b(May 20, 2025): "add compat support for RHEL 9.6"2b17b01(Jun 18, 2024): "fix gso.h compat code for RHEL 9.4"Impact
Affected Systems:
Repository Information
linux-compat.hRelated Issues
Similar RHEL backporting issues previously fixed: