From 3069463f2551956d6cbac43c2b3b2525ae68591d Mon Sep 17 00:00:00 2001 From: Vadim Fedorenko Date: Sun, 16 Jun 2024 23:31:50 +0100 Subject: [PATCH] ipt_NETFLOW: add compatibility with 6.8+ * add strlcpy definition as it was removed in 6.8 * replace strtoul with simple_strtoul which exists in all kernels and is proper interface to use * inline timeval_to_jiffies to follow new kernel build rules * replace check for in{4,6}_pton to remove unneeded functions Signed-off-by: Vadim Fedorenko --- compat.h | 56 ++++++++++++++++---------------------------------- gen_compat_def | 4 ++++ ipt_NETFLOW.c | 7 +++++-- 3 files changed, 27 insertions(+), 40 deletions(-) diff --git a/compat.h b/compat.h index 8461c3d..c4f29e9 100644 --- a/compat.h +++ b/compat.h @@ -216,7 +216,7 @@ struct timeval { long tv_usec; /* microseconds */ }; -unsigned long timeval_to_jiffies(const struct timeval *tv) +static inline unsigned long timeval_to_jiffies(const struct timeval *tv) { return timespec64_to_jiffies(&(struct timespec64){ tv->tv_sec, @@ -225,6 +225,20 @@ unsigned long timeval_to_jiffies(const struct timeval *tv) } #endif +#ifndef HAVE_STRLCPY +static inline size_t strlcpy(char *dest, const char *src, size_t size) +{ + size_t ret = strlen(src); + + if (size) { + size_t len = (ret >= size) ? size - 1 : ret; + __builtin_memcpy(dest, src, len); + dest[len] = '\0'; + } + return ret; +} +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) # ifdef ktime_to_timeval /* ktime_to_timeval is defined on 64bit and inline on 32bit cpu */ @@ -380,10 +394,10 @@ static int sockaddr_cmp(const struct sockaddr_storage *sa1, const struct sockadd return 0; } -#ifndef IN6PTON_XDIGIT +#ifndef HAVE_IN6_PTON #define hex_to_bin compat_hex_to_bin /* lib/hexdump.c */ -int hex_to_bin(char ch) +static inline int hex_to_bin(char ch) { if ((ch >= '0') && (ch <= '9')) return ch - '0'; @@ -593,7 +607,7 @@ int in6_pton(const char *src, int srclen, *end = s; return ret; } -#endif /* IN6PTON_XDIGIT */ +#endif /* HAVE_IN6_PTON */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,2,0) # define sock_create_kern(f, t, p, s) sock_create_kern(&init_net, f, t, p, s) @@ -712,40 +726,6 @@ static inline void do_gettimeofday(struct timeval *tv) } #endif -#define TOLOWER(x) ((x) | 0x20) -unsigned long long strtoul(const char *cp, char **endp, unsigned int base) -{ - unsigned long long result = 0; - - if (!base) { - if (cp[0] == '0') { - if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2])) - base = 16; - else - base = 8; - } else { - base = 10; - } - } - - if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x') - cp += 2; - - while (isxdigit(*cp)) { - unsigned int value; - - value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10; - if (value >= base) - break; - result = result * base + value; - cp++; - } - if (endp) - *endp = (char *)cp; - - return result; -} - #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,12,0) /* * find_module() is unexported in v5.12: diff --git a/gen_compat_def b/gen_compat_def index a9cb95e..f9796f7 100755 --- a/gen_compat_def +++ b/gen_compat_def @@ -129,6 +129,10 @@ kbuild_test_ref totalram_pages linux/mm.h kbuild_test_member nf_ct_event_notifier.ct_event net/netfilter/nf_conntrack_ecache.h # 6.4: 0199849acd07 ("sysctl: remove register_sysctl_paths()") kbuild_test_symbol register_sysctl_paths linux/sysctl.h +# 6.8: d26270061ae6 ("string: Remove strlcpy()") +kbuild_test_symbol strlcpy linux/string.h +# 2.6.18 lacks in6_pton and in4_pton +kbuild_test_symbol in6_pton linux/inet.h echo "// End of compat_def.h" diff --git a/ipt_NETFLOW.c b/ipt_NETFLOW.c index eee8074..3b717a3 100644 --- a/ipt_NETFLOW.c +++ b/ipt_NETFLOW.c @@ -29,6 +29,9 @@ #include #include #include +#if LINUX_VERSION_CODE > KERNEL_VERSION(5,10,0) +#include +#endif #include #include #include @@ -2396,7 +2399,7 @@ static int add_destinations(const char *ptr) ++end; if (succ && (*end == ':' || *end == '.' || *end == 'p' || *end == '#')) - sin6->sin6_port = htons(strtoul(++end, (char **)&end, 0)); + sin6->sin6_port = htons(simple_strtoul(++end, (char **)&end, 0)); if (succ && *end == '@') { ++end; sout->sin6_family = AF_INET6; @@ -2411,7 +2414,7 @@ static int add_destinations(const char *ptr) sin->sin_port = htons(2055); succ = in4_pton(ptr, len, (u8 *)&sin->sin_addr, -1, &end); if (succ && *end == ':') - sin->sin_port = htons(strtoul(++end, (char **)&end, 0)); + sin->sin_port = htons(simple_strtoul(++end, (char **)&end, 0)); if (succ && *end == '@') { ++end; sout->sin_family = AF_INET;