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