[prev in list] [next in list] [prev in thread] [next in thread] 

List:       netfilter-devel
Subject:    [PATCH] Autoloading of netfilter subsystems
From:       Jozsef Kadlecsik <kadlec () blackhole ! kfki ! hu>
Date:       2005-04-19 13:07:05
Message-ID: Pine.LNX.4.58.0504191452330.22052 () blackhole ! kfki ! hu
[Download RAW message or body]

Hi,

Attached patch implements the autoloading of subsystems which rely on
netfilter sockopt. For example one can type 'iptables -A ....' and module
'ip_tables' (and then 'iptable_filter', etc.) will automagically be loaded
in (if those are compiled as modules and automatic kernel module load is
compiled in).

Best regards,
Jozsef
-
E-mail  : kadlec@blackhole.kfki.hu, kadlec@sunserv.kfki.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : KFKI Research Institute for Particle and Nuclear Physics
          H-1525 Budapest 114, POB. 49, Hungary
["mod.patch" (TEXT/PLAIN)]

Autoload subsystems which use netfilter sockopts.

Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>

diff -urN --exclude-from=/usr/src/diff.exclude \
linux-2.6.11-ipset/include/linux/netfilter.h \
                linux-2.6.11-ipset-mod/include/linux/netfilter.h
--- linux-2.6.11-ipset/include/linux/netfilter.h	2005-03-02 08:38:09.000000000 +0100
+++ linux-2.6.11-ipset-mod/include/linux/netfilter.h	2005-04-19 07:15:38.000000000 \
+0200 @@ -56,6 +56,8 @@
 	int priority;
 };
 
+#define NF_SOCKOPT_MAXNAMELEN 32
+
 struct nf_sockopt_ops
 {
 	struct list_head list;
@@ -71,6 +73,9 @@
 	int get_optmax;
 	int (*get)(struct sock *sk, int optval, void __user *user, int *len);
 
+	/* Module name for autoloading */
+	char name[NF_SOCKOPT_MAXNAMELEN];
+
 	/* Number of users inside set() or get(). */
 	unsigned int use;
 	struct task_struct *cleanup_task;
diff -urN --exclude-from=/usr/src/diff.exclude \
linux-2.6.11-ipset/include/linux/netfilter_arp/arp_tables.h \
                linux-2.6.11-ipset-mod/include/linux/netfilter_arp/arp_tables.h
--- linux-2.6.11-ipset/include/linux/netfilter_arp/arp_tables.h	2005-03-02 \
                08:37:52.000000000 +0100
+++ linux-2.6.11-ipset-mod/include/linux/netfilter_arp/arp_tables.h	2005-04-19 \
06:41:53.000000000 +0200 @@ -18,6 +18,7 @@
 #endif
 #include <linux/compiler.h>
 #include <linux/netfilter_arp.h>
+#include <linux/netfilter_sockopts.h>
 
 #define ARPT_FUNCTION_MAXNAMELEN 30
 #define ARPT_TABLE_MAXNAMELEN 32
@@ -140,15 +141,15 @@
  * Unlike BSD Linux inherits IP options so you don't have to use a raw
  * socket for this. Instead we check rights in the calls.
  */
-#define ARPT_BASE_CTL		96	/* base for firewall socket options */
+#define ARPT_BASE_CTL		NF_ARPTABLES_BASE	/* base for firewall socket options */
 
 #define ARPT_SO_SET_REPLACE		(ARPT_BASE_CTL)
 #define ARPT_SO_SET_ADD_COUNTERS	(ARPT_BASE_CTL + 1)
-#define ARPT_SO_SET_MAX			ARPT_SO_SET_ADD_COUNTERS
+#define ARPT_SO_SET_MAX			NF_ARPTABLES_SET_MAX
 
 #define ARPT_SO_GET_INFO		(ARPT_BASE_CTL)
 #define ARPT_SO_GET_ENTRIES		(ARPT_BASE_CTL + 1)
-#define ARPT_SO_GET_MAX			ARPT_SO_GET_ENTRIES
+#define ARPT_SO_GET_MAX			NF_ARPTABLES_GET_MAX
 
 /* CONTINUE verdict for targets */
 #define ARPT_CONTINUE 0xFFFFFFFF
diff -urN --exclude-from=/usr/src/diff.exclude \
linux-2.6.11-ipset/include/linux/netfilter_bridge/ebtables.h \
                linux-2.6.11-ipset-mod/include/linux/netfilter_bridge/ebtables.h
--- linux-2.6.11-ipset/include/linux/netfilter_bridge/ebtables.h	2005-03-02 \
                08:38:26.000000000 +0100
+++ linux-2.6.11-ipset-mod/include/linux/netfilter_bridge/ebtables.h	2005-04-19 \
06:41:53.000000000 +0200 @@ -14,6 +14,7 @@
 #define __LINUX_BRIDGE_EFF_H
 #include <linux/if.h>
 #include <linux/netfilter_bridge.h>
+#include <linux/netfilter_sockopts.h>
 #include <linux/if_ether.h>
 
 #define EBT_TABLE_MAXNAMELEN 32
@@ -164,17 +165,17 @@
 };
 
 /* {g,s}etsockopt numbers */
-#define EBT_BASE_CTL            128
+#define EBT_BASE_CTL            NF_EBTABLES_BASE
 
 #define EBT_SO_SET_ENTRIES      (EBT_BASE_CTL)
 #define EBT_SO_SET_COUNTERS     (EBT_SO_SET_ENTRIES+1)
-#define EBT_SO_SET_MAX          (EBT_SO_SET_COUNTERS+1)
+#define EBT_SO_SET_MAX          NF_EBTABLES_SET_MAX
 
 #define EBT_SO_GET_INFO         (EBT_BASE_CTL)
 #define EBT_SO_GET_ENTRIES      (EBT_SO_GET_INFO+1)
 #define EBT_SO_GET_INIT_INFO    (EBT_SO_GET_ENTRIES+1)
 #define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1)
-#define EBT_SO_GET_MAX          (EBT_SO_GET_INIT_ENTRIES+1)
+#define EBT_SO_GET_MAX          NF_EBTABLES_GET_MAX
 
 #ifdef __KERNEL__
 
diff -urN --exclude-from=/usr/src/diff.exclude \
linux-2.6.11-ipset/include/linux/netfilter_ipv4/ip_tables.h \
                linux-2.6.11-ipset-mod/include/linux/netfilter_ipv4/ip_tables.h
--- linux-2.6.11-ipset/include/linux/netfilter_ipv4/ip_tables.h	2005-03-02 \
                08:38:10.000000000 +0100
+++ linux-2.6.11-ipset-mod/include/linux/netfilter_ipv4/ip_tables.h	2005-04-19 \
06:44:25.000000000 +0200 @@ -24,6 +24,7 @@
 #endif
 #include <linux/compiler.h>
 #include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_sockopts.h>
 
 #define IPT_FUNCTION_MAXNAMELEN 30
 #define IPT_TABLE_MAXNAMELEN 32
@@ -150,17 +151,17 @@
  * New IP firewall options for [gs]etsockopt at the RAW IP level.
  * Unlike BSD Linux inherits IP options so you don't have to use a raw
  * socket for this. Instead we check rights in the calls. */
-#define IPT_BASE_CTL		64	/* base for firewall socket options */
+#define IPT_BASE_CTL		NF_IPTABLES_BASE	/* base for firewall socket options */
 
 #define IPT_SO_SET_REPLACE	(IPT_BASE_CTL)
 #define IPT_SO_SET_ADD_COUNTERS	(IPT_BASE_CTL + 1)
-#define IPT_SO_SET_MAX		IPT_SO_SET_ADD_COUNTERS
+#define IPT_SO_SET_MAX		NF_IPTABLES_SET_MAX
 
 #define IPT_SO_GET_INFO			(IPT_BASE_CTL)
 #define IPT_SO_GET_ENTRIES		(IPT_BASE_CTL + 1)
 #define IPT_SO_GET_REVISION_MATCH	(IPT_BASE_CTL + 2)
 #define IPT_SO_GET_REVISION_TARGET	(IPT_BASE_CTL + 3)
-#define IPT_SO_GET_MAX			IPT_SO_GET_REVISION_TARGET
+#define IPT_SO_GET_MAX			NF_IPTABLES_GET_MAX
 
 /* CONTINUE verdict for targets */
 #define IPT_CONTINUE 0xFFFFFFFF
diff -urN --exclude-from=/usr/src/diff.exclude \
linux-2.6.11-ipset/include/linux/netfilter_ipv4.h \
                linux-2.6.11-ipset-mod/include/linux/netfilter_ipv4.h
--- linux-2.6.11-ipset/include/linux/netfilter_ipv4.h	2005-03-02 08:38:25.000000000 \
                +0100
+++ linux-2.6.11-ipset-mod/include/linux/netfilter_ipv4.h	2005-04-19 \
06:41:53.000000000 +0200 @@ -7,6 +7,7 @@
 
 #include <linux/config.h>
 #include <linux/netfilter.h>
+#include <linux/netfilter_sockopts.h>
 
 /* IP Cache bits. */
 /* Src IP address. */
@@ -69,7 +70,7 @@
 /* 2.0 firewalling went from 64 through 71 (and +256, +512, etc). */
 /* 2.2 firewalling (+ masq) went from 64 through 76 */
 /* 2.4 firewalling went 64 through 67. */
-#define SO_ORIGINAL_DST 80
+#define SO_ORIGINAL_DST	NF_IP_CT_BASE
 
 #ifdef __KERNEL__
 #ifdef CONFIG_NETFILTER_DEBUG
diff -urN --exclude-from=/usr/src/diff.exclude \
linux-2.6.11-ipset/include/linux/netfilter_ipv6/ip6_tables.h \
                linux-2.6.11-ipset-mod/include/linux/netfilter_ipv6/ip6_tables.h
--- linux-2.6.11-ipset/include/linux/netfilter_ipv6/ip6_tables.h	2005-03-02 \
                08:38:26.000000000 +0100
+++ linux-2.6.11-ipset-mod/include/linux/netfilter_ipv6/ip6_tables.h	2005-04-19 \
06:41:53.000000000 +0200 @@ -24,6 +24,7 @@
 #endif
 #include <linux/compiler.h>
 #include <linux/netfilter_ipv6.h>
+#include <linux/netfilter_sockopts.h>
 
 #define IP6T_FUNCTION_MAXNAMELEN 30
 #define IP6T_TABLE_MAXNAMELEN 32
@@ -152,15 +153,15 @@
  * New IP firewall options for [gs]etsockopt at the RAW IP level.
  * Unlike BSD Linux inherits IP options so you don't have to use
  * a raw socket for this. Instead we check rights in the calls. */
-#define IP6T_BASE_CTL			64	/* base for firewall socket options */
+#define IP6T_BASE_CTL			NF_IP6TABLES_BASE	/* base for firewall socket options */
 
 #define IP6T_SO_SET_REPLACE		(IP6T_BASE_CTL)
 #define IP6T_SO_SET_ADD_COUNTERS	(IP6T_BASE_CTL + 1)
-#define IP6T_SO_SET_MAX			IP6T_SO_SET_ADD_COUNTERS
+#define IP6T_SO_SET_MAX			NF_IP6TABLES_SET_MAX
 
 #define IP6T_SO_GET_INFO		(IP6T_BASE_CTL)
 #define IP6T_SO_GET_ENTRIES		(IP6T_BASE_CTL + 1)
-#define IP6T_SO_GET_MAX			IP6T_SO_GET_ENTRIES
+#define IP6T_SO_GET_MAX			NF_IP6TABLES_GET_MAX
 
 /* CONTINUE verdict for targets */
 #define IP6T_CONTINUE 0xFFFFFFFF
diff -urN --exclude-from=/usr/src/diff.exclude \
linux-2.6.11-ipset/include/linux/netfilter_sockopts.h \
                linux-2.6.11-ipset-mod/include/linux/netfilter_sockopts.h
--- linux-2.6.11-ipset/include/linux/netfilter_sockopts.h	1970-01-01 \
                01:00:00.000000000 +0100
+++ linux-2.6.11-ipset-mod/include/linux/netfilter_sockopts.h	2005-04-19 \
13:58:20.000000000 +0200 @@ -0,0 +1,88 @@
+#ifndef __LINUX_NETFILTER_SOCKOPTS_H
+#define __LINUX_NETFILTER_SOCKOPTS_H
+#include <linux/config.h>
+
+#ifndef NF_SOCKOPT_REG
+#define NF_SOCKOPT_REG(_var,_pf,_smin,_smax,_gmin,_gmax,_name)
+#endif
+
+/* PF: ARP */
+
+/* linux/netfilter_arp/arp_tables.h */
+#define NF_ARPTABLES_BASE	96
+#define NF_ARPTABLES_SET_MAX	(NF_ARPTABLES_BASE+1)
+#define NF_ARPTABLES_GET_MAX	(NF_ARPTABLES_BASE+1)
+
+#ifdef CONFIG_IP_NF_ARPTABLES_MODULE
+NF_SOCKOPT_REG(arp_sockopts_reg, 0, 
+	       NF_ARPTABLES_BASE, NF_ARPTABLES_SET_MAX,
+	       NF_ARPTABLES_BASE, NF_ARPTABLES_GET_MAX,
+	       "arp_tables")
+#endif
+
+/* PF: IPv4 */
+
+/* linux/netfilter_ipv4/ip_tables.h */
+#define NF_IPTABLES_BASE	64
+#define NF_IPTABLES_SET_MAX	(NF_IPTABLES_BASE+1)
+#define NF_IPTABLES_GET_MAX	(NF_IPTABLES_BASE+3)
+
+#ifdef CONFIG_IP_NF_IPTABLES_MODULE
+NF_SOCKOPT_REG(ipt_sockopts_reg, PF_INET,
+	       NF_IPTABLES_BASE, NF_IPTABLES_SET_MAX,
+	       NF_IPTABLES_BASE, NF_IPTABLES_GET_MAX,
+	       "ip_tables")
+#endif
+
+/* linux/netfilter_ipv4.h, autoloading via other modules */
+#define NF_IP_CT_BASE		80
+
+/* linux/netfilter_ipv4/ip_set.h */
+#define NF_IP_SET_BASE		83
+
+#ifdef CONFIG_IP_NF_SET_MODULE
+NF_SOCKOPT_REG(ipset_sockopts_reg, PF_INET,
+	       NF_IP_SET_BASE, NF_IP_SET_BASE,
+	       NF_IP_SET_BASE, NF_IP_SET_BASE,
+	       "ip_set")
+#endif
+
+/* linux/netfilter_bridge/ebtables.h */
+#define NF_EBTABLES_BASE	128
+#define NF_EBTABLES_SET_MAX	(NF_EBTABLES_BASE+1)
+#define NF_EBTABLES_GET_MAX	(NF_EBTABLES_BASE+3)
+
+#ifdef CONFIG_BRIDGE_NF_EBTABLES_MODULE
+NF_SOCKOPT_REG(ebt_sockopts_reg, PF_INET,
+	       NF_EBTABLES_BASE, NF_EBTABLES_SET_MAX,
+	       NF_EBTABLES_BASE, NF_EBTABLES_GET_MAX,
+	       "ebtables")
+#endif
+
+/* net/ip_vs.h */
+#define NF_IP_VS_BASE		(64+1024+64)
+#define NF_IP_VS_SET_MAX	(NF_IP_VS_BASE+15)
+#define NF_IP_VS_GET_MAX	(NF_IP_VS_BASE+7)
+
+#ifdef CONFIG_IP_VS_MODULE
+NF_SOCKOPT_REG(ipvs_sockopts_reg, PF_INET,
+	       NF_IP_VS_BASE, NF_IP_VS_SET_MAX,
+	       NF_IP_VS_BASE, NF_IP_VS_GET_MAX,
+	       "ip_vs")
+#endif
+
+/* PF: IPv6 */
+
+/* linux/netfilter_ipv6/ip6_tables.h */
+#define NF_IP6TABLES_BASE	64
+#define NF_IP6TABLES_SET_MAX	(NF_IP6TABLES_BASE+1)
+#define NF_IP6TABLES_GET_MAX	(NF_IP6TABLES_BASE+1)
+
+#ifdef CONFIG_IP6_NF_IPTABLES_MODULE
+NF_SOCKOPT_REG(ip6t_sockopts_reg, PF_INET6,
+	       NF_IP6TABLES_BASE, NF_IP6TABLES_SET_MAX,
+	       NF_IP6TABLES_BASE, NF_IP6TABLES_GET_MAX,
+	       "ip6_tables")
+#endif
+
+#endif /*__LINUX_NETFILTER_SOCKOPTS_H*/
diff -urN --exclude-from=/usr/src/diff.exclude linux-2.6.11-ipset/include/net/ip_vs.h \
                linux-2.6.11-ipset-mod/include/net/ip_vs.h
--- linux-2.6.11-ipset/include/net/ip_vs.h	2005-03-02 08:37:31.000000000 +0100
+++ linux-2.6.11-ipset-mod/include/net/ip_vs.h	2005-04-19 06:41:53.000000000 +0200
@@ -36,7 +36,7 @@
 /*
  *      IPVS socket options
  */
-#define IP_VS_BASE_CTL		(64+1024+64)		/* base */
+#define IP_VS_BASE_CTL		NF_IP_VS_BASE		/* base */
 
 #define IP_VS_SO_SET_NONE	IP_VS_BASE_CTL		/* just peek */
 #define IP_VS_SO_SET_INSERT	(IP_VS_BASE_CTL+1)
@@ -54,7 +54,7 @@
 #define IP_VS_SO_SET_RESTORE    (IP_VS_BASE_CTL+13)
 #define IP_VS_SO_SET_SAVE       (IP_VS_BASE_CTL+14)
 #define IP_VS_SO_SET_ZERO	(IP_VS_BASE_CTL+15)
-#define IP_VS_SO_SET_MAX	IP_VS_SO_SET_ZERO
+#define IP_VS_SO_SET_MAX	NF_IP_VS_SET_MAX
 
 #define IP_VS_SO_GET_VERSION	IP_VS_BASE_CTL
 #define IP_VS_SO_GET_INFO	(IP_VS_BASE_CTL+1)
@@ -64,7 +64,7 @@
 #define IP_VS_SO_GET_DEST	(IP_VS_BASE_CTL+5)	/* not used now */
 #define IP_VS_SO_GET_TIMEOUT	(IP_VS_BASE_CTL+6)
 #define IP_VS_SO_GET_DAEMON	(IP_VS_BASE_CTL+7)
-#define IP_VS_SO_GET_MAX	IP_VS_SO_GET_DAEMON
+#define IP_VS_SO_GET_MAX	NF_IP_VS_GET_MAX
 
 
 /*
diff -urN --exclude-from=/usr/src/diff.exclude \
                linux-2.6.11-ipset/net/core/netfilter.c \
                linux-2.6.11-ipset-mod/net/core/netfilter.c
--- linux-2.6.11-ipset/net/core/netfilter.c	2005-03-02 08:38:08.000000000 +0100
+++ linux-2.6.11-ipset-mod/net/core/netfilter.c	2005-04-19 13:58:21.000000000 +0200
@@ -18,6 +18,7 @@
 #include <linux/skbuff.h>
 #include <linux/wait.h>
 #include <linux/module.h>
+#include <linux/kmod.h>
 #include <linux/interrupt.h>
 #include <linux/if.h>
 #include <linux/netdevice.h>
@@ -60,6 +61,19 @@
 } queue_handler[NPROTO];
 static DEFINE_RWLOCK(queue_handler_lock);
 
+/* Known systems using netfilter sockopt */
+#define NF_SOCKOPT_REG(_var,_pf,_smin,_smax,_gmin,_gmax,_name)	\
+static struct nf_sockopt_ops _var = {	\
+	.pf		= _pf,		\
+	.set_optmin	= _smin,	\
+	.set_optmax	= _smax+1,	\
+	.get_optmin	= _gmin,	\
+	.get_optmax	= _gmax+1,	\
+	.name		= _name,	\
+};
+#include <linux/netfilter_sockopts.h>
+#undef NF_SOCKOPT_REG
+
 int nf_register_hook(struct nf_hook_ops *reg)
 {
 	struct list_head *i;
@@ -91,14 +105,9 @@
 	return max1 > min2 && min1 < max2;
 }
 
-/* Functions to register sockopt ranges (exclusive). */
-int nf_register_sockopt(struct nf_sockopt_ops *reg)
+static inline struct nf_sockopt_ops * __find_sockopt(struct nf_sockopt_ops *reg)
 {
 	struct list_head *i;
-	int ret = 0;
-
-	if (down_interruptible(&nf_sockopt_mutex) != 0)
-		return -EINTR;
 
 	list_for_each(i, &nf_sockopts) {
 		struct nf_sockopt_ops *ops = (struct nf_sockopt_ops *)i;
@@ -109,14 +118,48 @@
 				   reg->get_optmin, reg->get_optmax))) {
 			NFDEBUG("nf_sock overlap: %u-%u/%u-%u v %u-%u/%u-%u\n",
 				ops->set_optmin, ops->set_optmax, 
-				ops->get_optmin, ops->get_optmax, 
+				ops->get_optmin, ops->get_optmax,
 				reg->set_optmin, reg->set_optmax,
 				reg->get_optmin, reg->get_optmax);
-			ret = -EBUSY;
-			goto out;
+			return ops;
 		}
 	}
 
+	return NULL;
+}
+
+/* Register builtin sockopt ranges (exclusive) at init. */
+static void nf_sockopt_init(struct nf_sockopt_ops *reg)
+{
+	BUG_ON(__find_sockopt(reg));
+
+	list_add(&reg->list, &nf_sockopts);
+}
+
+/* Functions to register sockopt ranges (exclusive). */
+int nf_register_sockopt(struct nf_sockopt_ops *reg)
+{
+	struct nf_sockopt_ops *ops;
+	int ret = 0;
+
+	if (down_interruptible(&nf_sockopt_mutex) != 0)
+		return -EINTR;
+
+	ops = __find_sockopt(reg);
+	if (ops != NULL) {
+		if (ops->set_optmin == reg->set_optmin
+		    && ops->set_optmax == reg->set_optmax
+		    && ops->get_optmax == reg->get_optmax
+		    && ops->set == NULL
+		    && ops->get == NULL) {
+			ops->set = reg->set;
+			ops->get = reg->get;
+			INIT_LIST_HEAD(&reg->list);
+		} else
+			ret = -EBUSY;
+		goto out;
+	}
+
 	list_add(&reg->list, &nf_sockopts);
 out:
 	up(&nf_sockopt_mutex);
@@ -137,7 +180,16 @@
 		schedule();
 		goto restart;
 	}
-	list_del(&reg->list);
+	if (list_empty(&reg->list)) {
+		struct nf_sockopt_ops *ops = __find_sockopt(reg);
+		
+		BUG_ON(ops == NULL);
+		ops->set = NULL;
+		ops->get = NULL;
+		ops->cleanup_task = NULL;
+	} else
+		list_del(&reg->list);
+
 	up(&nf_sockopt_mutex);
 }
 
@@ -286,7 +338,7 @@
 
 /* Call get/setsockopt() */
 static int nf_sockopt(struct sock *sk, int pf, int val, 
-		      char __user *opt, int *len, int get)
+		      char __user *opt, int *len, int get, int load)
 {
 	struct list_head *i;
 	struct nf_sockopt_ops *ops;
@@ -301,6 +353,8 @@
 			if (get) {
 				if (val >= ops->get_optmin
 				    && val < ops->get_optmax) {
+				    	if (ops->get == NULL)
+				    		goto try_load;
 					ops->use++;
 					up(&nf_sockopt_mutex);
 					ret = ops->get(sk, val, opt, len);
@@ -309,6 +363,8 @@
 			} else {
 				if (val >= ops->set_optmin
 				    && val < ops->set_optmax) {
+				    	if (ops->set == NULL)
+				    		goto try_load;
 					ops->use++;
 					up(&nf_sockopt_mutex);
 					ret = ops->set(sk, val, opt, *len);
@@ -319,6 +375,15 @@
 	}
 	up(&nf_sockopt_mutex);
 	return -ENOPROTOOPT;
+
+ try_load:
+	up(&nf_sockopt_mutex);
+	if (load == 0)
+		return -ENOPROTOOPT;
+
+	request_module("%s", ops->name);
+
+	return nf_sockopt(sk, pf, val, opt, len, get, 0);
 	
  out:
 	down(&nf_sockopt_mutex);
@@ -332,12 +397,12 @@
 int nf_setsockopt(struct sock *sk, int pf, int val, char __user *opt,
 		  int len)
 {
-	return nf_sockopt(sk, pf, val, opt, &len, 0);
+	return nf_sockopt(sk, pf, val, opt, &len, 0, 1);
 }
 
 int nf_getsockopt(struct sock *sk, int pf, int val, char __user *opt, int *len)
 {
-	return nf_sockopt(sk, pf, val, opt, len, 1);
+	return nf_sockopt(sk, pf, val, opt, len, 1, 1);
 }
 
 static unsigned int nf_iterate(struct list_head *head,
@@ -825,6 +890,24 @@
 		for (h = 0; h < NF_MAX_HOOKS; h++)
 			INIT_LIST_HEAD(&nf_hooks[i][h]);
 	}
+#ifdef CONFIG_IP_NF_ARPTABLES_MODULE
+	nf_sockopt_init(&arp_sockopts_reg);
+#endif
+#ifdef CONFIG_IP_NF_IPTABLES_MODULE
+	nf_sockopt_init(&ipt_sockopts_reg);
+#endif
+#ifdef CONFIG_IP_NF_SET_MODULE
+	nf_sockopt_init(&ipset_sockopts_reg);
+#endif
+#ifdef CONFIG_BRIDGE_NF_EBTABLES_MODULE
+	nf_sockopt_init(&ebt_sockopts_reg);
+#endif
+#ifdef CONFIG_IP_VS_MODULE
+	nf_sockopt_init(&ipvs_sockopts_reg);
+#endif
+#ifdef CONFIG_IP6_NF_IPTABLES_MODULE
+	nf_sockopt_init(&ip6t_sockopts_reg);
+#endif
 }
 
 EXPORT_SYMBOL(ip_ct_attach);



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic