[GH-ISSUE #196] feat/awg3: PersistentKeepalive breaks setconf (EINVAL) — tools send string attr, kernel still reads u16 #112

Closed
opened 2026-10-13 21:06:40 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @sysbedlam on GitHub (Jul 28, 2026).
Original GitHub issue: https://github.com/amnezia-vpn/amneziawg-linux-kernel-module/issues/196

Summary

On feat/awg3, PersistentKeepalive (any value — plain integer or range) makes awg setconf fail with Unable to modify interface: Invalid argument. Every other new AWG3 field (HeaderProtectionKey, ContentPaddingAddition, timing ranges) plus all existing v1/v2 obfuscation fields (Jc/Jmin/Jmax, S1-S4, H1-H4 ranges, I1 tags) work fine — isolated this down to PersistentKeepalive specifically.

Root cause (cross-repo mismatch)

  • amneziawg-tools (feat/awg3, commit 05434ca) — src/ipc-linux.h:260 now writes this peer attribute as a string, presumably to support the new range syntax (20-30) documented for this field:
    mnl_attr_put_strz(nlh, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, peer->persistent_keepalive_interval);
    
  • amneziawg-linux-kernel-module (feat/awg3, commit f4cd9df) — src/netlink.c:724 still reads this attribute as a raw u16:
    const u16 persistent_keepalive_interval = nla_get_u16(...)
    
    and src/peer.h:57 still declares it as a plain scalar, not a range type:
    u16 persistent_keepalive_interval;
    

So tools sends a null-terminated string attribute, the kernel tries to read it with nla_get_u16 (expects a fixed 2-byte binary payload) → attribute validation fails → setconf returns EINVAL regardless of the value's format (confirmed with both PersistentKeepalive = 25 and PersistentKeepalive = 20-30).

Steps to reproduce

Built both repos at the commits above against a stock Ubuntu 22.04 kernel (5.15.0-186-generic), loaded the new kmod (clean load, no dmesg errors), then:

$ ip link add awgtest type amneziawg
$ cat t.conf
[Interface]
PrivateKey = <valid key>

[Peer]
PublicKey = <valid key>
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

$ awg setconf awgtest t.conf
Unable to modify interface: Invalid argument

Removing the PersistentKeepalive line alone makes the exact same config apply cleanly. Also confirmed the range form (PersistentKeepalive = 20-30) fails identically.

Expected

setconf accepts PersistentKeepalive (either scalar or range form, per the README's documented range,x type) without error.

Notes

  • Kernel module itself loads cleanly and is fully backward-compatible with existing v1/v2 configs (no PersistentKeepalive range support needed there) — only this one field is affected.
  • Happy to test a fix — have a throwaway VM with both repos already built at the commits above.
Originally created by @sysbedlam on GitHub (Jul 28, 2026). Original GitHub issue: https://github.com/amnezia-vpn/amneziawg-linux-kernel-module/issues/196 ## Summary On `feat/awg3`, `PersistentKeepalive` (any value — plain integer or range) makes `awg setconf` fail with `Unable to modify interface: Invalid argument`. Every other new AWG3 field (`HeaderProtectionKey`, `ContentPaddingAddition`, timing ranges) plus all existing v1/v2 obfuscation fields (`Jc/Jmin/Jmax`, `S1-S4`, `H1-H4` ranges, `I1` tags) work fine — isolated this down to `PersistentKeepalive` specifically. ## Root cause (cross-repo mismatch) - `amneziawg-tools` (`feat/awg3`, commit `05434ca`) — `src/ipc-linux.h:260` now writes this peer attribute as a **string**, presumably to support the new range syntax (`20-30`) documented for this field: ```c mnl_attr_put_strz(nlh, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, peer->persistent_keepalive_interval); ``` - `amneziawg-linux-kernel-module` (`feat/awg3`, commit `f4cd9df`) — `src/netlink.c:724` still reads this attribute as a raw **u16**: ```c const u16 persistent_keepalive_interval = nla_get_u16(...) ``` and `src/peer.h:57` still declares it as a plain scalar, not a range type: ```c u16 persistent_keepalive_interval; ``` So tools sends a null-terminated string attribute, the kernel tries to read it with `nla_get_u16` (expects a fixed 2-byte binary payload) → attribute validation fails → `setconf` returns `EINVAL` regardless of the value's format (confirmed with both `PersistentKeepalive = 25` and `PersistentKeepalive = 20-30`). ## Steps to reproduce Built both repos at the commits above against a stock Ubuntu 22.04 kernel (5.15.0-186-generic), loaded the new kmod (clean load, no dmesg errors), then: ``` $ ip link add awgtest type amneziawg $ cat t.conf [Interface] PrivateKey = <valid key> [Peer] PublicKey = <valid key> AllowedIPs = 0.0.0.0/0 PersistentKeepalive = 25 $ awg setconf awgtest t.conf Unable to modify interface: Invalid argument ``` Removing the `PersistentKeepalive` line alone makes the exact same config apply cleanly. Also confirmed the range form (`PersistentKeepalive = 20-30`) fails identically. ## Expected `setconf` accepts `PersistentKeepalive` (either scalar or range form, per the README's documented `range,x` type) without error. ## Notes - Kernel module itself loads cleanly and is fully backward-compatible with existing v1/v2 configs (no `PersistentKeepalive` range support needed there) — only this one field is affected. - Happy to test a fix — have a throwaway VM with both repos already built at the commits above.
Author
Owner

@ygurov commented on GitHub (Jul 29, 2026):

Hi @sysbedlam,
AWG 3.0 is not yet fully released. Please standby.
It will happen in a day or two

<!-- gh-comment-id:5119396578 --> @ygurov commented on GitHub (Jul 29, 2026): Hi @sysbedlam, AWG 3.0 is not yet fully released. Please standby. It will happen in a day or two
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
amnezia-vpn/amneziawg-linux-kernel-module#112
No description provided.