[GH-ISSUE #251] Introducing strscpy broke compatibility with older kernels. #136

Open
opened 2026-10-13 21:06:54 +00:00 by bsakaguchi · 2 comments
Owner

Originally created by @achpile on GitHub (Sep 16, 2026).
Original GitHub issue: https://github.com/amnezia-vpn/amneziawg-linux-kernel-module/issues/251

Here's the commit:

github.com/amnezia-vpn/amneziawg-linux-kernel-module@40c812ebc8

strscpy was introduced in kernel v4.3
so it is impossible to compile for older kernels.

Maybe something like this should help:

#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
static inline ssize_t strscpy(char * dest, const char * src, size_t count) {
	ssize_t res = strlcpy(dest, src, count);
	dest[count] = '\0';

	return res;
}
#endif
Originally created by @achpile on GitHub (Sep 16, 2026). Original GitHub issue: https://github.com/amnezia-vpn/amneziawg-linux-kernel-module/issues/251 Here's the commit: https://github.com/amnezia-vpn/amneziawg-linux-kernel-module/commit/40c812ebc827fda396818d2ed2cb61c0f7685e07 strscpy was introduced in kernel v4.3 so it is impossible to compile for older kernels. Maybe something like this should help: ``` #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0) static inline ssize_t strscpy(char * dest, const char * src, size_t count) { ssize_t res = strlcpy(dest, src, count); dest[count] = '\0'; return res; } #endif ```
Author
Owner

@achpile commented on GitHub (Sep 16, 2026):

UPD: I don't want to add new issue. There's also usage of ip6_dst_lookup_flow in socket.c.

In kernel v5.4.5 it is:

struct dst_entry *ip6_dst_lookup_flow(struct net *net, const struct sock *sk, struct flowi6 *fl6, const struct in6_addr *final_dst);

In kernel v5.4.4 it had less arguments:

struct dst_entry *ip6_dst_lookup_flow(const struct sock *sk, struct flowi6 *fl6, const struct in6_addr *final_dst);

So fix like that should do the trick:

#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 5)
#define ip6_dst_lookup_flow(a, b, c, d) ip6_dst_lookup_flow(b, c, d)
#endif
<!-- gh-comment-id:5699479908 --> @achpile commented on GitHub (Sep 16, 2026): UPD: I don't want to add new issue. There's also usage of ip6_dst_lookup_flow in socket.c. In kernel v5.4.5 it is: struct [dst_entry](https://elixir.bootlin.com/linux/v5.4.5/C/ident/dst_entry) *[ip6_dst_lookup_flow](https://elixir.bootlin.com/linux/v5.4.5/C/ident/ip6_dst_lookup_flow)(struct net *net, const struct [sock](https://elixir.bootlin.com/linux/v5.4.5/C/ident/sock) *sk, struct [flowi6](https://elixir.bootlin.com/linux/v5.4.5/C/ident/flowi6) *[fl6](https://elixir.bootlin.com/linux/v5.4.5/C/ident/fl6), const struct [in6_addr](https://elixir.bootlin.com/linux/v5.4.5/C/ident/in6_addr) *final_dst); In kernel v5.4.4 it had less arguments: struct [dst_entry](https://elixir.bootlin.com/linux/v5.4.4/C/ident/dst_entry) *[ip6_dst_lookup_flow](https://elixir.bootlin.com/linux/v5.4.4/C/ident/ip6_dst_lookup_flow)(const struct [sock](https://elixir.bootlin.com/linux/v5.4.4/C/ident/sock) *sk, struct [flowi6](https://elixir.bootlin.com/linux/v5.4.4/C/ident/flowi6) *[fl6](https://elixir.bootlin.com/linux/v5.4.4/C/ident/fl6), const struct [in6_addr](https://elixir.bootlin.com/linux/v5.4.4/C/ident/in6_addr) *final_dst); So fix like that should do the trick: ``` #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 5) #define ip6_dst_lookup_flow(a, b, c, d) ip6_dst_lookup_flow(b, c, d) #endif ```
Author
Owner

@achpile commented on GitHub (Sep 25, 2026):

Also before 3.14 ip6_dst_lookup_flow had syntax like this:

struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
const struct in6_addr *final_dst,
bool can_sleep);

There was can_sleep argument. So I guess correct way would be like this:

#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
#define ip6_dst_lookup_flow(a, b, c, d) ip6_dst_lookup_flow(b, c, d, false)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 5)
#define ip6_dst_lookup_flow(a, b, c, d) ip6_dst_lookup_flow(b, c, d)
#endif
<!-- gh-comment-id:5836861442 --> @achpile commented on GitHub (Sep 25, 2026): Also before 3.14 ip6_dst_lookup_flow had syntax like this: struct [dst_entry](https://elixir.bootlin.com/linux/v3.13.11/C/ident/dst_entry) *[ip6_dst_lookup_flow](https://elixir.bootlin.com/linux/v3.13.11/C/ident/ip6_dst_lookup_flow)(struct [sock](https://elixir.bootlin.com/linux/v3.13.11/C/ident/sock) *sk, struct [flowi6](https://elixir.bootlin.com/linux/v3.13.11/C/ident/flowi6) *[fl6](https://elixir.bootlin.com/linux/v3.13.11/C/ident/fl6), const struct [in6_addr](https://elixir.bootlin.com/linux/v3.13.11/C/ident/in6_addr) *final_dst, [bool](https://elixir.bootlin.com/linux/v3.13.11/C/ident/bool) [can_sleep](https://elixir.bootlin.com/linux/v3.13.11/C/ident/can_sleep)); There was `can_sleep` argument. So I guess correct way would be like this: ``` #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) #define ip6_dst_lookup_flow(a, b, c, d) ip6_dst_lookup_flow(b, c, d, false) #elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 5) #define ip6_dst_lookup_flow(a, b, c, d) ip6_dst_lookup_flow(b, c, d) #endif ```
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#136
No description provided.