From fbc6b140a51f4faa9b995eb965b6e69ebb541f3f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 10 Jan 2006 19:43:00 +0000 Subject: large target/linux cleanup git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@2877 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../patches/611-netfilter_condition.patch | 625 +++++++++++++++++++++ 1 file changed, 625 insertions(+) create mode 100644 target/linux/generic-2.4/patches/611-netfilter_condition.patch (limited to 'target/linux/generic-2.4/patches/611-netfilter_condition.patch') diff --git a/target/linux/generic-2.4/patches/611-netfilter_condition.patch b/target/linux/generic-2.4/patches/611-netfilter_condition.patch new file mode 100644 index 0000000000..6c16c29f0c --- /dev/null +++ b/target/linux/generic-2.4/patches/611-netfilter_condition.patch @@ -0,0 +1,625 @@ +diff -ruN linux-2.4.30-old/Documentation/Configure.help linux-2.4.30-new/Documentation/Configure.help +--- linux-2.4.30-old/Documentation/Configure.help 2005-11-13 21:52:27.000000000 +0100 ++++ linux-2.4.30-new/Documentation/Configure.help 2005-11-13 22:20:15.000000000 +0100 +@@ -2979,6 +2979,14 @@ + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + ++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'. ++ + conntrack match support + CONFIG_IP_NF_MATCH_CONNTRACK + This is a general conntrack match module, a superset of the state match. +@@ -3354,6 +3362,14 @@ + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + ++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'. ++ + Multiple port match support + CONFIG_IP6_NF_MATCH_MULTIPORT + Multiport matching allows you to match TCP or UDP packets based on +diff -ruN linux-2.4.30-old/include/linux/netfilter_ipv4/ipt_condition.h linux-2.4.30-new/include/linux/netfilter_ipv4/ipt_condition.h +--- linux-2.4.30-old/include/linux/netfilter_ipv4/ipt_condition.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.30-new/include/linux/netfilter_ipv4/ipt_condition.h 2005-11-13 22:20:14.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 -ruN linux-2.4.30-old/include/linux/netfilter_ipv6/ip6t_condition.h linux-2.4.30-new/include/linux/netfilter_ipv6/ip6t_condition.h +--- linux-2.4.30-old/include/linux/netfilter_ipv6/ip6t_condition.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.30-new/include/linux/netfilter_ipv6/ip6t_condition.h 2005-11-13 22:20:14.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 -ruN linux-2.4.30-old/net/ipv4/netfilter/Config.in linux-2.4.30-new/net/ipv4/netfilter/Config.in +--- linux-2.4.30-old/net/ipv4/netfilter/Config.in 2005-11-13 21:52:27.000000000 +0100 ++++ linux-2.4.30-new/net/ipv4/netfilter/Config.in 2005-11-13 22:20:15.000000000 +0100 +@@ -43,6 +43,7 @@ + dep_tristate ' netfilter MARK match support' CONFIG_IP_NF_MATCH_MARK $CONFIG_IP_NF_IPTABLES + dep_tristate ' Multiple port match support' CONFIG_IP_NF_MATCH_MULTIPORT $CONFIG_IP_NF_IPTABLES + 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 + dep_tristate ' recent match support' CONFIG_IP_NF_MATCH_RECENT $CONFIG_IP_NF_IPTABLES + dep_tristate ' ECN match support' CONFIG_IP_NF_MATCH_ECN $CONFIG_IP_NF_IPTABLES + dep_tristate ' peer to peer traffic match support' CONFIG_IP_NF_MATCH_IPP2P $CONFIG_IP_NF_IPTABLES +diff -ruN linux-2.4.30-old/net/ipv4/netfilter/Makefile linux-2.4.30-new/net/ipv4/netfilter/Makefile +--- linux-2.4.30-old/net/ipv4/netfilter/Makefile 2005-11-13 21:52:27.000000000 +0100 ++++ linux-2.4.30-new/net/ipv4/netfilter/Makefile 2005-11-13 22:20:15.000000000 +0100 +@@ -94,6 +94,7 @@ + obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o + obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o + obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o ++obj-$(CONFIG_IP_NF_MATCH_CONDITION) += ipt_condition.o + + obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o + +diff -ruN linux-2.4.30-old/net/ipv4/netfilter/ipt_condition.c linux-2.4.30-new/net/ipv4/netfilter/ipt_condition.c +--- linux-2.4.30-old/net/ipv4/netfilter/ipt_condition.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.30-new/net/ipv4/netfilter/ipt_condition.c 2005-11-13 22:20:14.000000000 +0100 +@@ -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 | ++| | ++| | ++| History: | ++| 2003-02-10 Second version with improved | ++| locking and simplified code. | ++| | ++| This software is distributed under the | ++| terms of the GNU GPL. | ++\*-------------------------------------------*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#ifndef CONFIG_PROC_FS ++#error "Proc file system support is required for this module" ++#endif ++ ++ ++MODULE_AUTHOR("Stephane Ouellette "); ++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, ++ const void *hdr, u_int16_t datalen, 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 struct ipt_ip *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 -ruN linux-2.4.30-old/net/ipv6/netfilter/Config.in linux-2.4.30-new/net/ipv6/netfilter/Config.in +--- linux-2.4.30-old/net/ipv6/netfilter/Config.in 2003-06-13 16:51:39.000000000 +0200 ++++ linux-2.4.30-new/net/ipv6/netfilter/Config.in 2005-11-13 22:20:15.000000000 +0100 +@@ -17,6 +17,7 @@ + if [ "$CONFIG_IP6_NF_IPTABLES" != "n" ]; then + # The simple matches. + 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 + dep_tristate ' MAC address match support' CONFIG_IP6_NF_MATCH_MAC $CONFIG_IP6_NF_IPTABLES + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' Routing header match support (EXPERIMENTAL)' CONFIG_IP6_NF_MATCH_RT $CONFIG_IP6_NF_IPTABLES +diff -ruN linux-2.4.30-old/net/ipv6/netfilter/Makefile linux-2.4.30-new/net/ipv6/netfilter/Makefile +--- linux-2.4.30-old/net/ipv6/netfilter/Makefile 2003-06-13 16:51:39.000000000 +0200 ++++ linux-2.4.30-new/net/ipv6/netfilter/Makefile 2005-11-13 22:20:15.000000000 +0100 +@@ -14,6 +14,7 @@ + # Link order matters here. + obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o + obj-$(CONFIG_IP6_NF_MATCH_LIMIT) += ip6t_limit.o ++obj-$(CONFIG_IP6_NF_MATCH_CONDITION) += ip6t_condition.o + obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o + obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o + obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o +diff -ruN linux-2.4.30-old/net/ipv6/netfilter/ip6t_condition.c linux-2.4.30-new/net/ipv6/netfilter/ip6t_condition.c +--- linux-2.4.30-old/net/ipv6/netfilter/ip6t_condition.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.30-new/net/ipv6/netfilter/ip6t_condition.c 2005-11-13 22:20:14.000000000 +0100 +@@ -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 | ++| | ++| | ++| This software is distributed under the | ++| terms of the GNU GPL. | ++\*-------------------------------------------*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#ifndef CONFIG_PROC_FS ++#error "Proc file system support is required for this module" ++#endif ++ ++ ++MODULE_AUTHOR("Stephane Ouellette "); ++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, ++ const void *hdr, u_int16_t datalen, 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 struct ip6t_ip6 *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 = ipt_register_match(&condition_match); ++ ++ if (errorcode) ++ remove_proc_entry("ip6t_condition", proc_net); ++ } else ++ errorcode = -EACCES; ++ ++ return errorcode; ++} ++ ++ ++static void __exit ++fini(void) ++{ ++ ipt_unregister_match(&condition_match); ++ remove_proc_entry("ip6t_condition", proc_net); ++} ++ ++module_init(init); ++module_exit(fini); -- cgit v1.2.3