SOURCES (LINUX_2_6): pom-ng-condition-20060829.patch (NEW) - condi...

cieciwa cieciwa at pld-linux.org
Tue Aug 29 12:33:26 CEST 2006


Author: cieciwa                      Date: Tue Aug 29 10:33:26 2006 GMT
Module: SOURCES                       Tag: LINUX_2_6
---- Log message:
- condition module.

---- Files affected:
SOURCES:
   pom-ng-condition-20060829.patch (NONE -> 1.1.2.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/pom-ng-condition-20060829.patch
diff -u /dev/null SOURCES/pom-ng-condition-20060829.patch:1.1.2.1
--- /dev/null	Tue Aug 29 12:33:26 2006
+++ SOURCES/pom-ng-condition-20060829.patch	Tue Aug 29 12:33:20 2006
@@ -0,0 +1,367 @@
+ include/linux/netfilter/xt_condition.h |   11 +
+ net/netfilter/Kconfig                  |   13 +
+ net/netfilter/Makefile                 |    1 
+ net/netfilter/xt_condition.c           |  315 +++++++++++++++++++++++++++++++++
+ 4 files changed, 340 insertions(+)
+
+diff -Nur --exclude '*.orig' linux.org/include/linux/netfilter/xt_condition.h linux/include/linux/netfilter/xt_condition.h
+--- linux.org/include/linux/netfilter/xt_condition.h	1970-01-01 00:00:00.000000000 +0000
++++ linux/include/linux/netfilter/xt_condition.h	2006-08-29 12:30:00.000000000 +0000
+@@ -0,0 +1,11 @@
++#ifndef _XT_CONDITION_H
++#define _XT_CONDITION_H
++
++#define CONDITION_NAME_LEN  32
++
++struct condition_info {
++	char name[CONDITION_NAME_LEN];
++	int  invert;
++};
++
++#endif /* _XT_CONDITION_H */
+diff -Nur --exclude '*.orig' linux.org/net/netfilter/Kconfig linux/net/netfilter/Kconfig
+--- linux.org/net/netfilter/Kconfig	2006-06-18 01:49:35.000000000 +0000
++++ linux/net/netfilter/Kconfig	2006-08-29 12:30:00.000000000 +0000
+@@ -388,5 +388,18 @@
+ 
+ 	  To compile it as a module, choose M here.  If unsure, say N.
+ 
++config NETFILTER_XT_MATCH_CONDITION
++        tristate  '"condition" match support'
++        depends on NETFILTER_XTABLES
++        help
++          This option allows you to match firewall rules against condition
++          variables stored in the /proc/net/nf_condition directory.
++
++          N.B.: older versions used /proc/net/ipt_condition. You can
++          reenable it with "compat_dir_name".
++
++          If you want to compile it as a module, say M here and read
++          Documentation/modules.txt.  If unsure, say `N'.
++
+ endmenu
+ 
+diff -Nur --exclude '*.orig' linux.org/net/netfilter/Makefile linux/net/netfilter/Makefile
+--- linux.org/net/netfilter/Makefile	2006-06-18 01:49:35.000000000 +0000
++++ linux/net/netfilter/Makefile	2006-08-29 12:30:00.000000000 +0000
+@@ -0,0 +0,1 @@
++obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_condition.o
+diff -Nur --exclude '*.orig' linux.org/net/netfilter/xt_condition.c linux/net/netfilter/xt_condition.c
+--- linux.org/net/netfilter/xt_condition.c	1970-01-01 00:00:00.000000000 +0000
++++ linux/net/netfilter/xt_condition.c	2006-08-29 12:30:00.000000000 +0000
+@@ -0,0 +1,315 @@
++/*-------------------------------------------*\
++|          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 at videotron.ca>          |
++|          Massimiliano Hofer     2006-05-15  |
++|          <max at nucleus.it>                   |
++|                                             |
++|  History:                                   |
++|    2003-02-10  Second version with improved |
++|                locking and simplified code. |
++|    2006-05-15  2.6.16 adaptations.          |
++|                Locking overhaul.            |
++|                Various bug fixes.           |
++|                                             |
++|  This software is distributed under the     |
++|  terms of the GNU GPL.                      |
++\*-------------------------------------------*/
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/proc_fs.h>
++#include <linux/spinlock.h>
++#include <asm/semaphore.h>
++#include <linux/string.h>
++#include <linux/list.h>
++#include <asm/atomic.h>
++#include <asm/uaccess.h>
++#include <linux/netfilter/x_tables.h>
++#include <linux/netfilter/xt_condition.h>
++
++#ifndef CONFIG_PROC_FS
++#error  "Proc file system support is required for this module"
++#endif
++
++/* Defaults, these can be overridden on the module command-line. */
++static unsigned int condition_list_perms = 0644;
++static unsigned int compat_dir_name = 0;
++static unsigned int condition_uid_perms = 0;
++static unsigned int condition_gid_perms = 0;
++
++MODULE_AUTHOR("Stephane Ouellette <ouellettes at videotron.ca> and Massimiliano Hofer <max at nucleus.it>");
++MODULE_DESCRIPTION("Allows rules to match against condition variables");
++MODULE_LICENSE("GPL");
++module_param(condition_list_perms, uint, 0600);
++MODULE_PARM_DESC(condition_list_perms,"permissions on /proc/net/nf_condition/* files");
++module_param(condition_uid_perms, uint, 0600);
++MODULE_PARM_DESC(condition_uid_perms,"user owner of /proc/net/nf_condition/* files");
++module_param(condition_gid_perms, uint, 0600);
++MODULE_PARM_DESC(condition_gid_perms,"group owner of /proc/net/nf_condition/* files");
++module_param(compat_dir_name, bool, 0400);
++MODULE_PARM_DESC(compat_dir_name,"use old style /proc/net/ipt_condition/* files");
++MODULE_ALIAS("ipt_condition");
++MODULE_ALIAS("ip6t_condition");
++
++struct condition_variable {
++	struct list_head list;
++	struct proc_dir_entry *status_proc;
++	unsigned int refcount;
++        int enabled;   /* TRUE == 1, FALSE == 0 */
++};
++
++/* proc_lock is a user context only semaphore used for write access */
++/*           to the conditions' list.                               */
++static DECLARE_MUTEX(proc_lock);
++
++static LIST_HEAD(conditions_list);
++static struct proc_dir_entry *proc_net_condition = NULL;
++static const char *dir_name;
++
++static int
++xt_condition_read_info(char __user *buffer, char **start, off_t offset,
++			int length, int *eof, void *data)
++{
++	struct condition_variable *var =
++	    (struct condition_variable *) data;
++
++	buffer[0] = (var->enabled) ? '1' : '0';
++	buffer[1] = '\n';
++	if (length>=2)
++		*eof = 1;
++
++	return 2;
++}
++
++
++static int
++xt_condition_write_info(struct file *file, const char __user *buffer,
++			 unsigned long length, void *data)
++{
++	struct condition_variable *var =
++	    (struct condition_variable *) data;
++	char newval;
++
++	if (length>0) {
++		if (get_user(newval, buffer))
++			return -EFAULT;
++	        /* Match only on the first character */
++		switch (newval) {
++		case '0':
++			var->enabled = 0;
++			break;
++		case '1':
++			var->enabled = 1;
++			break;
++		}
++	}
++
++	return (int) length;
++}
++
++
++static int
++match(const struct sk_buff *skb, const struct net_device *in,
++      const struct net_device *out, const struct xt_match *match,
++      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;
++
++	rcu_read_lock();
++	list_for_each_entry_rcu(var, &conditions_list, list) {
++		if (strcmp(info->name, var->status_proc->name) == 0) {
++			condition_status = var->enabled;
++			break;
++		}
++	}
++	rcu_read_unlock();
++
++	return condition_status ^ info->invert;
++}
++
++
++
++static int
++checkentry(const char *tablename, const void *ip,
++	   const struct xt_match *match,
++	   void *matchinfo, unsigned int matchsize,
++	   unsigned int hook_mask)
++{
++	static const char * const forbidden_names[]={ "", ".", ".." };
++	struct condition_info *info = (struct condition_info *) matchinfo;
++	struct list_head *pos;
++	struct condition_variable *var, *newvar;
++
++	int i;
++
++	/* We don't want a '/' in a proc file name. */
++	for (i=0; i < CONDITION_NAME_LEN && info->name[i] != '\0'; i++)
++		if (info->name[i] == '/')
++			return 0;
++	/* We can't handle file names longer than CONDITION_NAME_LEN and */
++	/* we want a NULL terminated string. */
++	if (i == CONDITION_NAME_LEN)
++		return 0;
++
++	/* We don't want certain reserved names. */
++	for (i=0; i < sizeof(forbidden_names)/sizeof(char *); i++)
++		if(strcmp(info->name, forbidden_names[i])==0)
++			return 0;
++
++	/* Let's acquire the lock, check for the condition and add it */
++	/* or increase the reference counter.                         */
++	if (down_interruptible(&proc_lock))
++	   return -EINTR;
++
++	list_for_each(pos, &conditions_list) {
++		var = list_entry(pos, struct condition_variable, list);
++		if (strcmp(info->name, var->status_proc->name) == 0) {
++			var->refcount++;
++			up(&proc_lock);
++			return 1;
++		}
++	}
++
++	/* At this point, we need to allocate a new condition variable. */
++	newvar = kmalloc(sizeof(struct condition_variable), GFP_KERNEL);
++
++	if (!newvar) {
++		up(&proc_lock);
++		return -ENOMEM;
++	}
++
++	/* Create the condition variable's proc file entry. */
++	newvar->status_proc = create_proc_entry(info->name, condition_list_perms, proc_net_condition);
++
++	if (!newvar->status_proc) {
++		kfree(newvar);
++		up(&proc_lock);
++		return -ENOMEM;
++	}
++
++	newvar->refcount = 1;
++	newvar->enabled = 0;
++	newvar->status_proc->owner = THIS_MODULE;
++	newvar->status_proc->data = newvar;
++	wmb();
++	newvar->status_proc->read_proc = xt_condition_read_info;
++	newvar->status_proc->write_proc = xt_condition_write_info;
++
++	list_add_rcu(&newvar->list, &conditions_list);
++
++	newvar->status_proc->uid = condition_uid_perms;
++	newvar->status_proc->gid = condition_gid_perms;
++
++	up(&proc_lock);
++
++	return 1;
++}
++
++
++static void
++destroy(const struct xt_match *match, void *matchinfo,
++	unsigned int matchsize)
++{
++	struct condition_info *info = (struct condition_info *) matchinfo;
++	struct list_head *pos;
++	struct condition_variable *var;
++
++	if (matchsize != XT_ALIGN(sizeof(struct condition_info)))
++		return;
++
++	down(&proc_lock);
++
++	list_for_each(pos, &conditions_list) {
++		var = list_entry(pos, struct condition_variable, list);
++		if (strcmp(info->name, var->status_proc->name) == 0) {
++			if (--var->refcount == 0) {
++				list_del_rcu(pos);
++				remove_proc_entry(var->status_proc->name, proc_net_condition);
++				up(&proc_lock);
++				/* synchronize_rcu() would be goog enough, but synchronize_net() */
++				/* guarantees that no packet will go out with the old rule after */
++				/* succesful removal.                                            */
++				synchronize_net();
++				kfree(var);
++				return;
++			}
++			break;
++		}
++	}
++
++	up(&proc_lock);
++}
++
++
++static struct xt_match condition_match = {
++	.name = "condition",
++	.family = AF_INET,
++	.matchsize = sizeof(struct condition_info),
++	.match = &match,
++	.checkentry = &checkentry,
++	.destroy = &destroy,
++	.me = THIS_MODULE
++};
++
++static struct xt_match condition6_match = {
++	.name = "condition",
++	.family = AF_INET6,
++	.matchsize = sizeof(struct condition_info),
++	.match = &match,
++	.checkentry = &checkentry,
++	.destroy = &destroy,
++	.me = THIS_MODULE
++};
++
++static int __init
++init(void)
++{
++	int errorcode;
++
++	dir_name = compat_dir_name? "ipt_condition": "nf_condition";
++
++	proc_net_condition = proc_mkdir(dir_name, proc_net);
++	if (!proc_net_condition) {
++		remove_proc_entry(dir_name, proc_net);
++		return -EACCES;
++	}
++
++        errorcode = xt_register_match(&condition_match);
++	if (errorcode) {
++		xt_unregister_match(&condition_match);
++		remove_proc_entry(dir_name, proc_net);
++		return errorcode;
++	}
++
++	errorcode = xt_register_match(&condition6_match);
++	if (errorcode) {
++		xt_unregister_match(&condition6_match);
++		xt_unregister_match(&condition_match);
++		remove_proc_entry(dir_name, proc_net);
++		return errorcode;
++	}
++
++	return 0;
++}
++
++
++static void __exit
++fini(void)
++{
++	xt_unregister_match(&condition6_match);
++	xt_unregister_match(&condition_match);
++	remove_proc_entry(dir_name, proc_net);
++}
++
++module_init(init);
++module_exit(fini);
================================================================


More information about the pld-cvs-commit mailing list