From 6a55739a9bf9fb890dbd1aa338057f394b766ab8 Mon Sep 17 00:00:00 2001
From: ABC <abc@openwall.com>
Date: Thu, 25 Nov 2021 21:07:29 +0300
Subject: [PATCH] Fix build on v5.15 (ct_event)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Comment: Refreshed to apply against 2.6 release
Bug: https://github.com/aabc/ipt-netflow/issues/186
Bug-Debian: https://bugs.debian.org/1005401
Bug-Ubuntu: https://bugs.launchpad.net/bugs/1951611

    CC [M]  ipt_NETFLOW.o
  ipt_NETFLOW.c: In function ‘netflow_conntrack_event’:
  ipt_NETFLOW.c:4622:31: error: ‘struct nf_ct_event_notifier’ has no member named ‘fcn’
   4622 |                 ret = notifier->fcn(events, item);
	|                               ^~
  ipt_NETFLOW.c: At top level:
  ipt_NETFLOW.c:4687:10: error: ‘struct nf_ct_event_notifier’ has no member named ‘fcn’
   4687 |         .fcn = netflow_conntrack_event
	|          ^~~
  ipt_NETFLOW.c:4687:16: error: initialization of ‘int (*)(unsigned int,  const struct nf_ct_event *)’ from incompatible pointer type ‘int (*)(const unsigned int,  struct nf_ct_event *)’ [-Werror=incompatible-pointer-types]
   4687 |         .fcn = netflow_conntrack_event
	|                ^~~~~~~~~~~~~~~~~~~~~~~
  ipt_NETFLOW.c:4687:16: note: (near initialization for ‘ctnl_notifier.ct_event’)
  ipt_NETFLOW.c: In function ‘unset_notifier_cb’:
  ipt_NETFLOW.c:5455:25: error: too many arguments to function ‘nf_conntrack_unregister_notifier’
   5455 |                         nf_conntrack_unregister_notifier(NET_ARG &ctnl_notifier);
	|                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  In file included from ./include/net/netfilter/nf_conntrack_core.h:18,
		   from ipt_NETFLOW.c:68:
  ./include/net/netfilter/nf_conntrack_ecache.h:88:6: note: declared here
     88 | void nf_conntrack_unregister_notifier(struct net *net);
	|      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Reported-by: https://github.com/rcmcronny
Fixes: #186
---
 compat.h       |  4 ++++
 gen_compat_def | 16 ++++++++++++++++
 ipt_NETFLOW.c  | 16 +++++++++++-----
 3 files changed, 31 insertions(+), 5 deletions(-)

--- a/compat.h
+++ b/compat.h
@@ -775,4 +775,8 @@
 }
 #endif
 
+#ifndef HAVE_NF_CT_EVENT_NOTIFIER_CT_EVENT
+# define ct_event fcn
+#endif
+
 #endif /* COMPAT_NETFLOW_H */
--- a/gen_compat_def
+++ b/gen_compat_def
@@ -72,6 +72,20 @@
 	EOF
 }
 
+# Test that struct have member
+kbuild_test_member() {
+  echo -n "Test member $* " >&2
+  structname=${1%.*}
+  member=${1#*.}
+  def=${1^^}
+  def=${def//./_}
+  kbuild_test_compile $def "struct $1" ${2-} <<-EOF
+	#include <linux/module.h>
+	${2:+#include <$2>}
+	MODULE_LICENSE("GPL");
+	typeof(((struct $structname*)0)->$member) test;
+	EOF
+}
 echo "// Autogenerated for $KDIR"
 echo
 
@@ -87,6 +101,8 @@
 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
+# b86c0e6429da ("netfilter: ecache: prepare for event notifier merge")
+kbuild_test_member nf_ct_event_notifier.ct_event net/netfilter/nf_conntrack_ecache.h
 
 echo "// End of compat_def.h"
 
--- a/ipt_NETFLOW.c
+++ b/ipt_NETFLOW.c
@@ -4597,7 +4597,7 @@
 #ifdef CONFIG_NF_NAT_NEEDED
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
 static struct nf_ct_event_notifier *saved_event_cb __read_mostly = NULL;
-static int netflow_conntrack_event(const unsigned int events, struct nf_ct_event *item)
+static int netflow_conntrack_event(const unsigned int events, const struct nf_ct_event *item)
 #else
 static int netflow_conntrack_event(struct notifier_block *this, unsigned long events, void *ptr)
 #endif
@@ -4619,7 +4619,7 @@
 	/* Call netlink first. */
 	notifier = rcu_dereference(saved_event_cb);
 	if (likely(notifier))
-		ret = notifier->fcn(events, item);
+		ret = notifier->ct_event(events, item);
 #endif
 	if (unlikely(!natevents))
 		return ret;
@@ -4684,7 +4684,7 @@
 };
 #else
 static struct nf_ct_event_notifier ctnl_notifier = {
-	.fcn = netflow_conntrack_event
+	.ct_event = netflow_conntrack_event
 };
 #endif /* since 2.6.31 */
 #endif /* CONFIG_NF_NAT_NEEDED */
@@ -5451,9 +5451,15 @@
 
 	notifier = rcu_dereference(nf_conntrack_event_cb);
 	if (notifier == &ctnl_notifier) {
-		if (saved_event_cb == NULL)
+		if (saved_event_cb == NULL) {
+#ifdef HAVE_NF_CT_EVENT_NOTIFIER_CT_EVENT
+			/* b86c0e6429da ("netfilter: ecache: prepare for event
+			 * notifier merge") */
+			nf_conntrack_unregister_notifier(net);
+#else
 			nf_conntrack_unregister_notifier(NET_ARG &ctnl_notifier);
-		else
+#endif
+		} else
 			rcu_assign_pointer(nf_conntrack_event_cb, saved_event_cb);
 	} else
 		printk(KERN_ERR "ipt_NETFLOW: natevents already disabled.\n");
