All of lore.kernel.org
 help / color / mirror / Atom feed
* Fix the condition extension for 2.6.16 kernels
@ 2006-03-30 21:51 Massimiliano Hofer
  2006-03-31  2:09 ` Krzysztof Oledzki
  0 siblings, 1 reply; 3+ messages in thread
From: Massimiliano Hofer @ 2006-03-30 21:51 UTC (permalink / raw)
  To: netfilter-devel


[-- Attachment #1.1: Type: text/plain, Size: 3123 bytes --]

Hi,
this is my first contribution to this project, so I suggest you to test it 
before accepting my code.
Anyway I did a really simple fix for the condition extension for 2.6.16 
kernels.


diff -Nur 
patch-o-matic-ng-20060329.orig/patchlets/condition/linux/net/ipv4/netfilter/ipt_condition.c 
patch-o-matic-ng-20060329/patchlets/condition/linux/net/ipv4/netfilter/ipt_condition.c
--- 
patch-o-matic-ng-20060329.orig/patchlets/condition/linux/net/ipv4/netfilter/ipt_condition.c 
2003-12-18 19:47:52.000000000 +0100
+++ 
patch-o-matic-ng-20060329/patchlets/condition/linux/net/ipv4/netfilter/ipt_condition.c      
2006-03-30 23:41:13.000000000 +0200
@@ -92,7 +92,7 @@
 static int
 match(const struct sk_buff *skb, const struct net_device *in,
       const struct net_device *out, const void *matchinfo, int offset,
-      const void *hdr, u_int16_t datalen, int *hotdrop)
+      unsigned int protoff, int *hotdrop)
 {
        const struct condition_info *info =
            (const struct condition_info *) matchinfo;
@@ -116,7 +116,7 @@


 static int
-checkentry(const char *tablename, const struct ipt_ip *ip,
+checkentry(const char *tablename, const void *ip,
           void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
 {
        struct condition_info *info = (struct condition_info *) matchinfo;
diff -Nur 
patch-o-matic-ng-20060329.orig/patchlets/condition/linux/net/ipv6/netfilter/ip6t_condition.c 
patch-o-matic-ng-20060329/patchlets/condition/linux/net/ipv6/netfilter/ip6t_condition.c
--- 
patch-o-matic-ng-20060329.orig/patchlets/condition/linux/net/ipv6/netfilter/ip6t_condition.c        
2003-12-20 17:38:19.000000000 +0100
+++ 
patch-o-matic-ng-20060329/patchlets/condition/linux/net/ipv6/netfilter/ip6t_condition.c     
2006-03-30 23:41:01.000000000 +0200
@@ -88,7 +88,7 @@
 static int
 match(const struct sk_buff *skb, const struct net_device *in,
       const struct net_device *out, const void *matchinfo, int offset,
-      const void *hdr, u_int16_t datalen, int *hotdrop)
+      unsigned int protoff, int *hotdrop)
 {
        const struct condition6_info *info =
            (const struct condition6_info *) matchinfo;
@@ -112,7 +112,7 @@


 static int
-checkentry(const char *tablename, const struct ip6t_ip6 *ip,
+checkentry(const char *tablename, const void *ip,
           void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
 {
        struct condition6_info *info =
@@ -232,7 +232,7 @@
        proc_net_condition = proc_mkdir("ip6t_condition", proc_net);

        if (proc_net_condition) {
-               errorcode = ipt_register_match(&condition_match);
+               errorcode = ip6t_register_match(&condition_match);

                if (errorcode)
                        remove_proc_entry("ip6t_condition", proc_net);
@@ -246,7 +246,7 @@
 static void __exit
 fini(void)
 {
-       ipt_unregister_match(&condition_match);
+       ip6t_unregister_match(&condition_match);
        remove_proc_entry("ip6t_condition", proc_net);
 }



-- 
Bye,
   Massimiliano Hofer
        Nucleus

[-- Attachment #1.2: condition.patch --]
[-- Type: text/x-diff, Size: 2715 bytes --]

diff -Nur patch-o-matic-ng-20060329.orig/patchlets/condition/linux/net/ipv4/netfilter/ipt_condition.c patch-o-matic-ng-20060329/patchlets/condition/linux/net/ipv4/netfilter/ipt_condition.c
--- patch-o-matic-ng-20060329.orig/patchlets/condition/linux/net/ipv4/netfilter/ipt_condition.c	2003-12-18 19:47:52.000000000 +0100
+++ patch-o-matic-ng-20060329/patchlets/condition/linux/net/ipv4/netfilter/ipt_condition.c	2006-03-30 23:41:13.000000000 +0200
@@ -92,7 +92,7 @@
 static int
 match(const struct sk_buff *skb, const struct net_device *in,
       const struct net_device *out, const void *matchinfo, int offset,
-      const void *hdr, u_int16_t datalen, int *hotdrop)
+      unsigned int protoff, int *hotdrop)
 {
 	const struct condition_info *info =
 	    (const struct condition_info *) matchinfo;
@@ -116,7 +116,7 @@
 
 
 static int
-checkentry(const char *tablename, const struct ipt_ip *ip,
+checkentry(const char *tablename, const void *ip,
 	   void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
 {
 	struct condition_info *info = (struct condition_info *) matchinfo;
diff -Nur patch-o-matic-ng-20060329.orig/patchlets/condition/linux/net/ipv6/netfilter/ip6t_condition.c patch-o-matic-ng-20060329/patchlets/condition/linux/net/ipv6/netfilter/ip6t_condition.c
--- patch-o-matic-ng-20060329.orig/patchlets/condition/linux/net/ipv6/netfilter/ip6t_condition.c	2003-12-20 17:38:19.000000000 +0100
+++ patch-o-matic-ng-20060329/patchlets/condition/linux/net/ipv6/netfilter/ip6t_condition.c	2006-03-30 23:41:01.000000000 +0200
@@ -88,7 +88,7 @@
 static int
 match(const struct sk_buff *skb, const struct net_device *in,
       const struct net_device *out, const void *matchinfo, int offset,
-      const void *hdr, u_int16_t datalen, int *hotdrop)
+      unsigned int protoff, int *hotdrop)
 {
 	const struct condition6_info *info =
 	    (const struct condition6_info *) matchinfo;
@@ -112,7 +112,7 @@
 
 
 static int
-checkentry(const char *tablename, const struct ip6t_ip6 *ip,
+checkentry(const char *tablename, const void *ip,
 	   void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
 {
 	struct condition6_info *info =
@@ -232,7 +232,7 @@
 	proc_net_condition = proc_mkdir("ip6t_condition", proc_net);
 
 	if (proc_net_condition) {
-	        errorcode = ipt_register_match(&condition_match);
+	        errorcode = ip6t_register_match(&condition_match);
 
 		if (errorcode)
 			remove_proc_entry("ip6t_condition", proc_net);
@@ -246,7 +246,7 @@
 static void __exit
 fini(void)
 {
-	ipt_unregister_match(&condition_match);
+	ip6t_unregister_match(&condition_match);
 	remove_proc_entry("ip6t_condition", proc_net);
 }
 

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Fix the condition extension for 2.6.16 kernels
  2006-03-30 21:51 Fix the condition extension for 2.6.16 kernels Massimiliano Hofer
@ 2006-03-31  2:09 ` Krzysztof Oledzki
  2006-03-31 13:11   ` Massimiliano Hofer
  0 siblings, 1 reply; 3+ messages in thread
From: Krzysztof Oledzki @ 2006-03-31  2:09 UTC (permalink / raw)
  To: Massimiliano Hofer; +Cc: netfilter-devel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 596 bytes --]



On Thu, 30 Mar 2006, Massimiliano Hofer wrote:

> Hi,
Hi,

> this is my first contribution to this project, so I suggest you to test it
> before accepting my code.

I think you should create a linux-2.6 directory as this modification 
prevents this extension from being usable in 2.4 kernels.

> Anyway I did a really simple fix for the condition extension for 2.6.16
> kernels.

BTW: Does it work or only compiles? ;) I remember some mails about porting 
condition to 2.6 raporting kernel crashes when accessing the proc 
interface.

Best regards,

 				Krzysztof Olędzki

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Fix the condition extension for 2.6.16 kernels
  2006-03-31  2:09 ` Krzysztof Oledzki
@ 2006-03-31 13:11   ` Massimiliano Hofer
  0 siblings, 0 replies; 3+ messages in thread
From: Massimiliano Hofer @ 2006-03-31 13:11 UTC (permalink / raw)
  To: netfilter-devel


[-- Attachment #1.1: Type: text/plain, Size: 860 bytes --]

On Friday 31 March 2006 4:09 am, Krzysztof Oledzki wrote:

> I think you should create a linux-2.6 directory as this modification
> prevents this extension from being usable in 2.4 kernels.

Here you go.

> > Anyway I did a really simple fix for the condition extension for 2.6.16
> > kernels.
>
> BTW: Does it work or only compiles? ;) I remember some mails about porting
> condition to 2.6 raporting kernel crashes when accessing the proc
> interface.

I tested it with IPv4 on x86 and x86_64. Everything works as expected, but the 
more testing the better, so you are welcome to do some more. :)

I don't have an IPv6 environment on hand and did no testing with it. I'll try 
to setup an IPv6 network in the coming days, but I think I should aim for a 
full merge of ipt and ip6t.

-- 
Saluti,
   Massimiliano Hofer
        Nucleus

[-- Attachment #1.2: condition.patch --]
[-- Type: text/x-diff, Size: 21363 bytes --]

diff -Nur patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/Documentation/Configure.help.ladd patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/Documentation/Configure.help.ladd
--- patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/Documentation/Configure.help.ladd	1970-01-01 01:00:00.000000000 +0100
+++ patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/Documentation/Configure.help.ladd	2004-03-05 10:30:25.000000000 +0100
@@ -0,0 +1,8 @@
+CONFIG_IP_NF_MATCH_TOS
+Condition variable match support
+CONFIG_IP_NF_MATCH_CONDITION
+  This option allows you to match firewall rules against condition
+  variables stored in the /proc/net/ipt_condition directory.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
diff -Nur patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/Documentation/Configure.help.ladd_2 patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/Documentation/Configure.help.ladd_2
--- patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/Documentation/Configure.help.ladd_2	1970-01-01 01:00:00.000000000 +0100
+++ patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/Documentation/Configure.help.ladd_2	2004-03-05 10:30:25.000000000 +0100
@@ -0,0 +1,8 @@
+CONFIG_IP6_NF_MATCH_MARK
+Condition variable match support
+CONFIG_IP6_NF_MATCH_CONDITION
+  This option allows you to match firewall rules against condition
+  variables stored in the /proc/net/ipt_condition directory.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
diff -Nur patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/include/linux/netfilter_ipv4/ipt_condition.h patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/include/linux/netfilter_ipv4/ipt_condition.h
--- patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/include/linux/netfilter_ipv4/ipt_condition.h	1970-01-01 01:00:00.000000000 +0100
+++ patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/include/linux/netfilter_ipv4/ipt_condition.h	2003-12-18 19:47:52.000000000 +0100
@@ -0,0 +1,11 @@
+#ifndef __IPT_CONDITION_MATCH__
+#define __IPT_CONDITION_MATCH__
+
+#define CONDITION_NAME_LEN  32
+
+struct condition_info {
+	char name[CONDITION_NAME_LEN];
+	int  invert;
+};
+
+#endif
diff -Nur patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/include/linux/netfilter_ipv6/ip6t_condition.h patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/include/linux/netfilter_ipv6/ip6t_condition.h
--- patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/include/linux/netfilter_ipv6/ip6t_condition.h	1970-01-01 01:00:00.000000000 +0100
+++ patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/include/linux/netfilter_ipv6/ip6t_condition.h	2003-12-20 17:38:19.000000000 +0100
@@ -0,0 +1,11 @@
+#ifndef __IP6T_CONDITION_MATCH__
+#define __IP6T_CONDITION_MATCH__
+
+#define CONDITION6_NAME_LEN  32
+
+struct condition6_info {
+	char name[CONDITION6_NAME_LEN];
+	int  invert;
+};
+
+#endif
diff -Nur patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/net/ipv4/netfilter/Config.in.ladd patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/net/ipv4/netfilter/Config.in.ladd
--- patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/net/ipv4/netfilter/Config.in.ladd	1970-01-01 01:00:00.000000000 +0100
+++ patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/net/ipv4/netfilter/Config.in.ladd	2003-12-18 19:47:52.000000000 +0100
@@ -0,0 +1,2 @@
+  dep_tristate '  TOS match support' CONFIG_IP_NF_MATCH_TOS $CONFIG_IP_NF_IPTABLES
+  dep_tristate '  condition match support' CONFIG_IP_NF_MATCH_CONDITION $CONFIG_IP_NF_IPTABLES
diff -Nur patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/net/ipv4/netfilter/ipt_condition.c patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/net/ipv4/netfilter/ipt_condition.c
--- patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/net/ipv4/netfilter/ipt_condition.c	1970-01-01 01:00:00.000000000 +0100
+++ patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/net/ipv4/netfilter/ipt_condition.c	2006-03-30 23:41:13.000000000 +0200
@@ -0,0 +1,256 @@
+/*-------------------------------------------*\
+|          Netfilter Condition Module         |
+|                                             |
+|  Description: This module allows firewall   |
+|    rules to match using condition variables |
+|    stored in /proc files.                   |
+|                                             |
+|  Author: Stephane Ouellette     2002-10-22  |
+|          <ouellettes@videotron.ca>          |
+|                                             |
+|  History:                                   |
+|    2003-02-10  Second version with improved |
+|                locking and simplified code. |
+|                                             |
+|  This software is distributed under the     |
+|  terms of the GNU GPL.                      |
+\*-------------------------------------------*/
+
+#include<linux/module.h>
+#include<linux/proc_fs.h>
+#include<linux/spinlock.h>
+#include<linux/string.h>
+#include<asm/atomic.h>
+#include<linux/netfilter_ipv4/ip_tables.h>
+#include<linux/netfilter_ipv4/ipt_condition.h>
+
+
+#ifndef CONFIG_PROC_FS
+#error  "Proc file system support is required for this module"
+#endif
+
+
+MODULE_AUTHOR("Stephane Ouellette <ouellettes@videotron.ca>");
+MODULE_DESCRIPTION("Allows rules to match against condition variables");
+MODULE_LICENSE("GPL");
+
+
+struct condition_variable {
+	struct condition_variable *next;
+	struct proc_dir_entry *status_proc;
+	atomic_t refcount;
+        int enabled;   /* TRUE == 1, FALSE == 0 */
+};
+
+
+static rwlock_t list_lock;
+static struct condition_variable *head = NULL;
+static struct proc_dir_entry *proc_net_condition = NULL;
+
+
+static int
+ipt_condition_read_info(char *buffer, char **start, off_t offset,
+			int length, int *eof, void *data)
+{
+	struct condition_variable *var =
+	    (struct condition_variable *) data;
+
+	if (offset == 0) {
+		*start = buffer;
+		buffer[0] = (var->enabled) ? '1' : '0';
+		buffer[1] = '\n';
+		return 2;
+	}
+
+	*eof = 1;
+	return 0;
+}
+
+
+static int
+ipt_condition_write_info(struct file *file, const char *buffer,
+			 unsigned long length, void *data)
+{
+	struct condition_variable *var =
+	    (struct condition_variable *) data;
+
+	if (length) {
+	        /* Match only on the first character */
+		switch (buffer[0]) {
+		case '0':
+			var->enabled = 0;
+			break;
+		case '1':
+			var->enabled = 1;
+		}
+	}
+
+	return (int) length;
+}
+
+
+static int
+match(const struct sk_buff *skb, const struct net_device *in,
+      const struct net_device *out, const void *matchinfo, int offset,
+      unsigned int protoff, int *hotdrop)
+{
+	const struct condition_info *info =
+	    (const struct condition_info *) matchinfo;
+	struct condition_variable *var;
+	int condition_status = 0;
+
+	read_lock(&list_lock);
+
+	for (var = head; var; var = var->next) {
+		if (strcmp(info->name, var->status_proc->name) == 0) {
+			condition_status = var->enabled;
+			break;
+		}
+	}
+
+	read_unlock(&list_lock);
+
+	return condition_status ^ info->invert;
+}
+
+
+
+static int
+checkentry(const char *tablename, const void *ip,
+	   void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
+{
+	struct condition_info *info = (struct condition_info *) matchinfo;
+	struct condition_variable *var, *newvar;
+
+	if (matchsize != IPT_ALIGN(sizeof(struct condition_info)))
+		return 0;
+
+	/* The first step is to check if the condition variable already exists. */
+	/* Here, a read lock is sufficient because we won't change the list */
+	read_lock(&list_lock);
+
+	for (var = head; var; var = var->next) {
+		if (strcmp(info->name, var->status_proc->name) == 0) {
+			atomic_inc(&var->refcount);
+			read_unlock(&list_lock);
+			return 1;
+		}
+	}
+
+	read_unlock(&list_lock);
+
+	/* At this point, we need to allocate a new condition variable */
+	newvar = kmalloc(sizeof(struct condition_variable), GFP_KERNEL);
+
+	if (!newvar)
+		return -ENOMEM;
+
+	/* Create the condition variable's proc file entry */
+	newvar->status_proc = create_proc_entry(info->name, 0644, proc_net_condition);
+
+	if (!newvar->status_proc) {
+	  /*
+	   * There are two possibilities:
+	   *  1- Another condition variable with the same name has been created, which is valid.
+	   *  2- There was a memory allocation error.
+	   */
+		kfree(newvar);
+		read_lock(&list_lock);
+
+		for (var = head; var; var = var->next) {
+			if (strcmp(info->name, var->status_proc->name) == 0) {
+				atomic_inc(&var->refcount);
+				read_unlock(&list_lock);
+				return 1;
+			}
+		}
+
+		read_unlock(&list_lock);
+		return -ENOMEM;
+	}
+
+	atomic_set(&newvar->refcount, 1);
+	newvar->enabled = 0;
+	newvar->status_proc->owner = THIS_MODULE;
+	newvar->status_proc->data = newvar;
+	wmb();
+	newvar->status_proc->read_proc = ipt_condition_read_info;
+	newvar->status_proc->write_proc = ipt_condition_write_info;
+
+	write_lock(&list_lock);
+
+	newvar->next = head;
+	head = newvar;
+
+	write_unlock(&list_lock);
+
+	return 1;
+}
+
+
+static void
+destroy(void *matchinfo, unsigned int matchsize)
+{
+	struct condition_info *info = (struct condition_info *) matchinfo;
+	struct condition_variable *var, *prev = NULL;
+
+	if (matchsize != IPT_ALIGN(sizeof(struct condition_info)))
+		return;
+
+	write_lock(&list_lock);
+
+	for (var = head; var && strcmp(info->name, var->status_proc->name);
+	     prev = var, var = var->next);
+
+	if (var && atomic_dec_and_test(&var->refcount)) {
+		if (prev)
+			prev->next = var->next;
+		else
+			head = var->next;
+
+		write_unlock(&list_lock);
+		remove_proc_entry(var->status_proc->name, proc_net_condition);
+		kfree(var);
+	} else
+		write_unlock(&list_lock);
+}
+
+
+static struct ipt_match condition_match = {
+	.name = "condition",
+	.match = &match,
+	.checkentry = &checkentry,
+	.destroy = &destroy,
+	.me = THIS_MODULE
+};
+
+
+static int __init
+init(void)
+{
+	int errorcode;
+
+	rwlock_init(&list_lock);
+	proc_net_condition = proc_mkdir("ipt_condition", proc_net);
+
+	if (proc_net_condition) {
+	        errorcode = ipt_register_match(&condition_match);
+
+		if (errorcode)
+			remove_proc_entry("ipt_condition", proc_net);
+	} else
+		errorcode = -EACCES;
+
+	return errorcode;
+}
+
+
+static void __exit
+fini(void)
+{
+	ipt_unregister_match(&condition_match);
+	remove_proc_entry("ipt_condition", proc_net);
+}
+
+module_init(init);
+module_exit(fini);
diff -Nur patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/net/ipv4/netfilter/Kconfig.ladd patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/net/ipv4/netfilter/Kconfig.ladd
--- patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/net/ipv4/netfilter/Kconfig.ladd	1970-01-01 01:00:00.000000000 +0100
+++ patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/net/ipv4/netfilter/Kconfig.ladd	2004-05-06 14:46:50.000000000 +0200
@@ -0,0 +1,9 @@
+config IP_NF_MATCH_CONDITION
+	tristate  'condition match support'
+	depends on IP_NF_IPTABLES
+	help
+	  This option allows you to match firewall rules against condition
+	  variables stored in the /proc/net/ipt_condition directory.
+	
+	  If you want to compile it as a module, say M here and read
+	  Documentation/modules.txt.  If unsure, say `N'.
diff -Nur patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/net/ipv4/netfilter/Makefile.ladd patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/net/ipv4/netfilter/Makefile.ladd
--- patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/net/ipv4/netfilter/Makefile.ladd	1970-01-01 01:00:00.000000000 +0100
+++ patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/net/ipv4/netfilter/Makefile.ladd	2003-12-18 19:47:52.000000000 +0100
@@ -0,0 +1,2 @@
+obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
+obj-$(CONFIG_IP_NF_MATCH_CONDITION) += ipt_condition.o
diff -Nur patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/net/ipv6/netfilter/Config.in.ladd patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/net/ipv6/netfilter/Config.in.ladd
--- patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/net/ipv6/netfilter/Config.in.ladd	1970-01-01 01:00:00.000000000 +0100
+++ patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/net/ipv6/netfilter/Config.in.ladd	2003-12-23 12:41:10.000000000 +0100
@@ -0,0 +1,2 @@
+  dep_tristate '  limit match support' CONFIG_IP6_NF_MATCH_LIMIT $CONFIG_IP6_NF_IPTABLES
+  dep_tristate '  condition match support' CONFIG_IP6_NF_MATCH_CONDITION $CONFIG_IP6_NF_IPTABLES
diff -Nur patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/net/ipv6/netfilter/ip6t_condition.c patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/net/ipv6/netfilter/ip6t_condition.c
--- patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/net/ipv6/netfilter/ip6t_condition.c	1970-01-01 01:00:00.000000000 +0100
+++ patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/net/ipv6/netfilter/ip6t_condition.c	2006-03-30 23:41:01.000000000 +0200
@@ -0,0 +1,254 @@
+/*-------------------------------------------*\
+|    Netfilter Condition Module for IPv6      |
+|                                             |
+|  Description: This module allows firewall   |
+|    rules to match using condition variables |
+|    stored in /proc files.                   |
+|                                             |
+|  Author: Stephane Ouellette     2003-02-10  |
+|          <ouellettes@videotron.ca>          |
+|                                             |
+|  This software is distributed under the     |
+|  terms of the GNU GPL.                      |
+\*-------------------------------------------*/
+
+#include<linux/module.h>
+#include<linux/proc_fs.h>
+#include<linux/spinlock.h>
+#include<linux/string.h>
+#include<asm/atomic.h>
+#include<linux/netfilter_ipv6/ip6_tables.h>
+#include<linux/netfilter_ipv6/ip6t_condition.h>
+
+
+#ifndef CONFIG_PROC_FS
+#error  "Proc file system support is required for this module"
+#endif
+
+
+MODULE_AUTHOR("Stephane Ouellette <ouellettes@videotron.ca>");
+MODULE_DESCRIPTION("Allows rules to match against condition variables");
+MODULE_LICENSE("GPL");
+
+
+struct condition_variable {
+	struct condition_variable *next;
+	struct proc_dir_entry *status_proc;
+	atomic_t refcount;
+        int enabled; /* TRUE == 1, FALSE == 0 */
+};
+
+
+static rwlock_t list_lock;
+static struct condition_variable *head = NULL;
+static struct proc_dir_entry *proc_net_condition = NULL;
+
+
+static int
+ipt_condition_read_info(char *buffer, char **start, off_t offset,
+			int length, int *eof, void *data)
+{
+	struct condition_variable *var =
+	    (struct condition_variable *) data;
+
+	if (offset == 0) {
+		*start = buffer;
+		buffer[0] = (var->enabled) ? '1' : '0';
+		buffer[1] = '\n';
+		return 2;
+	}
+
+	*eof = 1;
+	return 0;
+}
+
+
+static int
+ipt_condition_write_info(struct file *file, const char *buffer,
+			 unsigned long length, void *data)
+{
+	struct condition_variable *var =
+	    (struct condition_variable *) data;
+
+	if (length) {
+	        /* Match only on the first character */
+		switch (buffer[0]) {
+		case '0':
+			var->enabled = 0;
+			break;
+		case '1':
+			var->enabled = 1;
+		}
+	}
+
+	return (int) length;
+}
+
+
+static int
+match(const struct sk_buff *skb, const struct net_device *in,
+      const struct net_device *out, const void *matchinfo, int offset,
+      unsigned int protoff, int *hotdrop)
+{
+	const struct condition6_info *info =
+	    (const struct condition6_info *) matchinfo;
+	struct condition_variable *var;
+	int condition_status = 0;
+
+	read_lock(&list_lock);
+
+	for (var = head; var; var = var->next) {
+		if (strcmp(info->name, var->status_proc->name) == 0) {
+			condition_status = var->enabled;
+			break;
+		}
+	}
+
+	read_unlock(&list_lock);
+
+	return condition_status ^ info->invert;
+}
+
+
+
+static int
+checkentry(const char *tablename, const void *ip,
+	   void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
+{
+	struct condition6_info *info =
+	    (struct condition6_info *) matchinfo;
+	struct condition_variable *var, *newvar;
+
+	if (matchsize != IP6T_ALIGN(sizeof(struct condition6_info)))
+		return 0;
+
+	/* The first step is to check if the condition variable already exists. */
+	/* Here, a read lock is sufficient because we won't change the list */
+	read_lock(&list_lock);
+
+	for (var = head; var; var = var->next) {
+		if (strcmp(info->name, var->status_proc->name) == 0) {
+			atomic_inc(&var->refcount);
+			read_unlock(&list_lock);
+			return 1;
+		}
+	}
+
+	read_unlock(&list_lock);
+
+	/* At this point, we need to allocate a new condition variable */
+	newvar = kmalloc(sizeof(struct condition_variable), GFP_KERNEL);
+
+	if (!newvar)
+		return -ENOMEM;
+
+	/* Create the condition variable's proc file entry */
+	newvar->status_proc = create_proc_entry(info->name, 0644, proc_net_condition);
+
+	if (!newvar->status_proc) {
+	  /*
+	   * There are two possibilities:
+	   *  1- Another condition variable with the same name has been created, which is valid.
+	   *  2- There was a memory allocation error.
+	   */
+		kfree(newvar);
+		read_lock(&list_lock);
+
+		for (var = head; var; var = var->next) {
+			if (strcmp(info->name, var->status_proc->name) == 0) {
+				atomic_inc(&var->refcount);
+				read_unlock(&list_lock);
+				return 1;
+			}
+		}
+
+		read_unlock(&list_lock);
+		return -ENOMEM;
+	}
+
+	atomic_set(&newvar->refcount, 1);
+	newvar->enabled = 0;
+	newvar->status_proc->owner = THIS_MODULE;
+	newvar->status_proc->data = newvar;
+	wmb();
+	newvar->status_proc->read_proc = ipt_condition_read_info;
+	newvar->status_proc->write_proc = ipt_condition_write_info;
+
+	write_lock(&list_lock);
+
+	newvar->next = head;
+	head = newvar;
+
+	write_unlock(&list_lock);
+
+	return 1;
+}
+
+
+static void
+destroy(void *matchinfo, unsigned int matchsize)
+{
+	struct condition6_info *info =
+	    (struct condition6_info *) matchinfo;
+	struct condition_variable *var, *prev = NULL;
+
+	if (matchsize != IP6T_ALIGN(sizeof(struct condition6_info)))
+		return;
+
+	write_lock(&list_lock);
+
+	for (var = head; var && strcmp(info->name, var->status_proc->name);
+	     prev = var, var = var->next);
+
+	if (var && atomic_dec_and_test(&var->refcount)) {
+		if (prev)
+			prev->next = var->next;
+		else
+			head = var->next;
+
+		write_unlock(&list_lock);
+		remove_proc_entry(var->status_proc->name, proc_net_condition);
+		kfree(var);
+	} else
+		write_unlock(&list_lock);
+}
+
+
+static struct ip6t_match condition_match = {
+	.name = "condition",
+	.match = &match,
+	.checkentry = &checkentry,
+	.destroy = &destroy,
+	.me = THIS_MODULE
+};
+
+
+static int __init
+init(void)
+{
+	int errorcode;
+
+	rwlock_init(&list_lock);
+	proc_net_condition = proc_mkdir("ip6t_condition", proc_net);
+
+	if (proc_net_condition) {
+	        errorcode = ip6t_register_match(&condition_match);
+
+		if (errorcode)
+			remove_proc_entry("ip6t_condition", proc_net);
+	} else
+		errorcode = -EACCES;
+
+	return errorcode;
+}
+
+
+static void __exit
+fini(void)
+{
+	ip6t_unregister_match(&condition_match);
+	remove_proc_entry("ip6t_condition", proc_net);
+}
+
+module_init(init);
+module_exit(fini);
diff -Nur patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/net/ipv6/netfilter/Kconfig.ladd patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/net/ipv6/netfilter/Kconfig.ladd
--- patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/net/ipv6/netfilter/Kconfig.ladd	1970-01-01 01:00:00.000000000 +0100
+++ patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/net/ipv6/netfilter/Kconfig.ladd	2004-05-06 14:46:50.000000000 +0200
@@ -0,0 +1,9 @@
+config IP6_NF_MATCH_CONDITION
+	tristate  'condition match support'
+	depends on IP6_NF_IPTABLES
+	help
+	  This option allows you to match firewall rules against condition
+	  variables stored in the /proc/net/ipt_condition directory.
+	
+	  If you want to compile it as a module, say M here and read
+	  Documentation/modules.txt.  If unsure, say `N'.
diff -Nur patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/net/ipv6/netfilter/Makefile.ladd patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/net/ipv6/netfilter/Makefile.ladd
--- patch-o-matic-ng-20060329.orig/patchlets/condition/linux-2.6.16/net/ipv6/netfilter/Makefile.ladd	1970-01-01 01:00:00.000000000 +0100
+++ patch-o-matic-ng-20060329/patchlets/condition/linux-2.6.16/net/ipv6/netfilter/Makefile.ladd	2006-03-31 15:04:14.000000000 +0200
@@ -0,0 +1 @@
+obj-$(CONFIG_IP6_NF_MATCH_CONDITION) += ip6t_condition.o

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2006-03-31 13:11 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-03-30 21:51 Fix the condition extension for 2.6.16 kernels Massimiliano Hofer
2006-03-31  2:09 ` Krzysztof Oledzki
2006-03-31 13:11   ` Massimiliano Hofer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.