diff --git a/compat.h b/compat.h
index 8461c3d..23b0e8f 100644
--- a/compat.h
+++ b/compat.h
@@ -76,12 +76,14 @@ union nf_inet_addr {
 #  define BEFORE2632(x,y)
 # endif
 
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
-#  define ctl_table struct ctl_table
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(6,11,0)
+#  define s_ctl_table const struct ctl_table
+# elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
+#  define s_ctl_table struct ctl_table
 # endif
 
-# ifndef HAVE_GRSECURITY_H
-#  define ctl_table_no_const ctl_table
+# if !defined(HAVE_GRSECURITY_H) && LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
+#  define ctl_table_no_const struct ctl_table
 # endif
 #endif
 
@@ -216,7 +218,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 +227,10 @@ unsigned long timeval_to_jiffies(const struct timeval *tv)
 }
 #endif
 
+#if !defined(HAVE_STRSCPY) && !defined(strscpy)
+#define strscpy strlcpy
+#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 +386,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 +599,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 +718,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..b8339e8 100755
--- a/gen_compat_def
+++ b/gen_compat_def
@@ -80,6 +80,15 @@ kbuild_test_ref() {
 	void *test = &$1;
 	EOF
 }
+
+# Test symbol if include exists
+kbuild_test_symbol_include() {
+  echo "Test file exists $KDIR/include/$2" >&2
+  if [ -f $KDIR/include/$2 ]; then
+    kbuild_test_symbol $*
+  fi
+}
+
 # Test that struct is defined.
 kbuild_test_struct() {
   echo -n "Test struct $* " >&2
@@ -121,7 +130,9 @@ kbuild_test_symbol nf_bridge_info_get linux/netfilter_bridge.h
 # Stumbled on 5.9
 kbuild_test_struct vlan_dev_priv linux/if_vlan.h
 # Kernel version check broken by centos8
-kbuild_test_symbol put_unaligned_be24 asm/unaligned.h
+kbuild_test_symbol_include put_unaligned_be24 asm-generic/unaligned.h
+kbuild_test_symbol_include put_unaligned_be24 linux/unaligned/generic.h
+kbuild_test_symbol_include put_unaligned_be24 linux/unaligned.h
 # totalram_pages changed from atomic to inline function.
 kbuild_test_symbol totalram_pages linux/mm.h
 kbuild_test_ref    totalram_pages linux/mm.h
@@ -129,6 +140,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 strscpy 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..ac8bea8 100644
--- a/ipt_NETFLOW.c
+++ b/ipt_NETFLOW.c
@@ -29,6 +29,10 @@
 #include <linux/in6.h>
 #include <linux/inet.h>
 #include <linux/kernel.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(5,10,0)
+#include <linux/kstrtox.h>
+#endif
 #include <linux/ip.h>
 #include <linux/udp.h>
 #include <linux/icmp.h>
@@ -67,8 +71,11 @@
 # include <net/netfilter/nf_conntrack.h>
 # include <net/netfilter/nf_conntrack_core.h>
 #endif
-#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6,12,0)
 #include <asm/unaligned.h>
+#else
+#include <linux/unaligned.h>
+#endif
 #ifdef HAVE_LLIST
 	/* llist.h is officially defined since linux 3.1,
 	 * but centos6 have it backported on its 2.6.32.el6 */
@@ -1519,7 +1526,7 @@ static int switch_promisc(int newpromisc)
 
 #ifdef CONFIG_SYSCTL
 /* sysctl /proc/sys/net/netflow */
-static int hsize_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
+static int hsize_procctl(s_ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
 			 void __user *buffer, size_t *lenp, loff_t *fpos)
 {
 	int ret, hsize;
@@ -1536,7 +1543,7 @@ static int hsize_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *filp
 		return ret;
 }
 
-static int sndbuf_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
+static int sndbuf_procctl(s_ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
 			 void __user *buffer, size_t *lenp, loff_t *fpos)
 {
 	int ret;
@@ -1571,7 +1578,7 @@ static int sndbuf_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *fil
 }
 
 static void free_templates(void);
-static int destination_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
+static int destination_procctl(s_ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
 			 void __user *buffer, size_t *lenp, loff_t *fpos)
 {
 	int ret;
@@ -1588,7 +1595,7 @@ static int destination_procctl(ctl_table *ctl, int write, BEFORE2632(struct file
 }
 
 #ifdef ENABLE_AGGR
-static int aggregation_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
+static int aggregation_procctl(s_ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
 			 void __user *buffer, size_t *lenp, loff_t *fpos)
 {
 	int ret;
@@ -1603,7 +1610,7 @@ static int aggregation_procctl(ctl_table *ctl, int write, BEFORE2632(struct file
 #endif
 
 #ifdef ENABLE_PROMISC
-static int promisc_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
+static int promisc_procctl(s_ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
 			 void __user *buffer, size_t *lenp, loff_t *fpos)
 {
 	int newpromisc = promisc;
@@ -1620,7 +1627,7 @@ static int promisc_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *fi
 
 #ifdef ENABLE_SAMPLER
 static int parse_sampler(char *ptr);
-static int sampler_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
+static int sampler_procctl(s_ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
 			 void __user *buffer, size_t *lenp, loff_t *fpos)
 {
 	int ret;
@@ -1653,7 +1660,7 @@ static int sampler_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *fi
 
 #ifdef SNMP_RULES
 static int add_snmp_rules(char *ptr);
-static int snmp_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
+static int snmp_procctl(s_ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
 			 void __user *buffer, size_t *lenp, loff_t *fpos)
 {
        int ret;
@@ -1678,7 +1685,7 @@ static void clear_ipt_netflow_stat(void)
 	}
 }
 
-static int flush_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
+static int flush_procctl(s_ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
 			 void __user *buffer, size_t *lenp, loff_t *fpos)
 {
 	int ret;
@@ -1707,7 +1714,7 @@ static int flush_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *filp
 	return ret;
 }
 
-static int protocol_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
+static int protocol_procctl(s_ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
 			 void __user *buffer, size_t *lenp, loff_t *fpos)
 {
 	int ret;
@@ -1740,7 +1747,7 @@ static int protocol_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *f
 #ifdef CONFIG_NF_NAT_NEEDED
 static void register_ct_events(void);
 static void unregister_ct_events(void);
-static int natevents_procctl(ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
+static int natevents_procctl(s_ctl_table *ctl, int write, BEFORE2632(struct file *filp,)
 			 void __user *buffer, size_t *lenp, loff_t *fpos)
 {
 	int ret;
@@ -1777,7 +1784,7 @@ static void ctl_table_renumber(ctl_table *table)
 #define _CTL_NAME(x)
 #define ctl_table_renumber(x)
 #endif
-static ctl_table netflow_sysctl_table[] = {
+static ctl_table_no_const netflow_sysctl_table[] = {
 	{
 		.procname	= "active_timeout",
 		.mode		= 0644,
@@ -1905,7 +1912,9 @@ static ctl_table netflow_sysctl_table[] = {
 		.proc_handler	= &natevents_procctl,
 	},
 #endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6,11,0)
 	{ }
+#endif
 };
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
@@ -2396,7 +2405,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 +2420,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;
@@ -4087,7 +4096,7 @@ static int ethtool_drvinfo(unsigned char *ptr, size_t size, struct net_device *d
 		ops->get_drvinfo(dev, &info);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
 	else if (dev->dev.parent && dev->dev.parent->driver) {
-		strlcpy(info.driver, dev->dev.parent->driver->name, sizeof(info.driver));
+		strscpy(info.driver, dev->dev.parent->driver->name, sizeof(info.driver));
 	}
 #endif
 	n = scnprintf(ptr, len, "%s", info.driver);
@@ -5684,7 +5693,7 @@ static int __init ipt_netflow_init(void)
 	if (!destination)
 		destination = destination_buf;
 	if (destination != destination_buf) {
-		strlcpy(destination_buf, destination, sizeof(destination_buf));
+		strscpy(destination_buf, destination, sizeof(destination_buf));
 		destination = destination_buf;
 	}
 	if (add_destinations(destination) < 0)
@@ -5694,7 +5703,7 @@ static int __init ipt_netflow_init(void)
 	if (!aggregation)
 		aggregation = aggregation_buf;
 	if (aggregation != aggregation_buf) {
-		strlcpy(aggregation_buf, aggregation, sizeof(aggregation_buf));
+		strscpy(aggregation_buf, aggregation, sizeof(aggregation_buf));
 		aggregation = aggregation_buf;
 	}
 	add_aggregation(aggregation);
@@ -5704,7 +5713,7 @@ static int __init ipt_netflow_init(void)
 	if (!sampler)
 		sampler = sampler_buf;
 	if (sampler != sampler_buf) {
-		strlcpy(sampler_buf, sampler, sizeof(sampler_buf));
+		strscpy(sampler_buf, sampler, sizeof(sampler_buf));
 		sampler = sampler_buf;
 	}
 	parse_sampler(sampler);
@@ -5721,7 +5730,7 @@ static int __init ipt_netflow_init(void)
 	if (!snmp_rules)
 		snmp_rules = snmp_rules_buf;
 	if (snmp_rules != snmp_rules_buf) {
-		strlcpy(snmp_rules_buf, snmp_rules, sizeof(snmp_rules_buf));
+		strscpy(snmp_rules_buf, snmp_rules, sizeof(snmp_rules_buf));
 		snmp_rules = snmp_rules_buf;
 	}
 	add_snmp_rules(snmp_rules);