diff options
| author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2007-01-01 04:42:50 +0000 | 
|---|---|---|
| committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2007-01-01 04:42:50 +0000 | 
| commit | 6d52fd57a32febf42a6be4d0a5dfd5411c93e447 (patch) | |
| tree | 48b373284e31d942ee3f1c9570e15dfe08feef71 /target/linux/generic-2.6/patches | |
| parent | cde9f30b2a8540f7adc3dc8cd6a28f894ee56437 (diff) | |
reorder netfilter patches, update layer7 kernel to latest version, should improve stability
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@5950 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/generic-2.6/patches')
| -rw-r--r-- | target/linux/generic-2.6/patches/100-netfilter_layer7_2.8.patch (renamed from target/linux/generic-2.6/patches/100-netfilter_layer7_2.1nbd.patch) | 560 | ||||
| -rw-r--r-- | target/linux/generic-2.6/patches/101-netfilter_layer7_pktmatch.patch | 108 | ||||
| -rw-r--r-- | target/linux/generic-2.6/patches/110-ipp2p_0.8.1rc1.patch (renamed from target/linux/generic-2.6/patches/101-ipp2p_0.8.1rc1.patch) | 0 | ||||
| -rw-r--r-- | target/linux/generic-2.6/patches/120-openswan-2.4.0.kernel-2.6-natt.patch (renamed from target/linux/generic-2.6/patches/102-openswan-2.4.0.kernel-2.6-natt.patch) | 0 | ||||
| -rw-r--r-- | target/linux/generic-2.6/patches/130-netfilter-ipset.patch (renamed from target/linux/generic-2.6/patches/103-netfilter-ipset.patch) | 0 | ||||
| -rw-r--r-- | target/linux/generic-2.6/patches/140-netfilter_time.patch (renamed from target/linux/generic-2.6/patches/105-netfilter_time.patch) | 0 | ||||
| -rw-r--r-- | target/linux/generic-2.6/patches/150-netfilter_imq.patch (renamed from target/linux/generic-2.6/patches/106-netfilter_imq.patch) | 0 | ||||
| -rw-r--r-- | target/linux/generic-2.6/patches/160-netfilter_route.patch (renamed from target/linux/generic-2.6/patches/108-netfilter_route.patch) | 0 | 
8 files changed, 382 insertions, 286 deletions
| diff --git a/target/linux/generic-2.6/patches/100-netfilter_layer7_2.1nbd.patch b/target/linux/generic-2.6/patches/100-netfilter_layer7_2.8.patch index 62571c6bf..876423cac 100644 --- a/target/linux/generic-2.6/patches/100-netfilter_layer7_2.1nbd.patch +++ b/target/linux/generic-2.6/patches/100-netfilter_layer7_2.8.patch @@ -1,6 +1,6 @@ -diff -urN linux-2.6.19.old/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.19.dev/include/linux/netfilter_ipv4/ip_conntrack.h ---- linux-2.6.19.old/include/linux/netfilter_ipv4/ip_conntrack.h	2006-11-29 22:57:37.000000000 +0100 -+++ linux-2.6.19.dev/include/linux/netfilter_ipv4/ip_conntrack.h	2006-12-14 03:13:37.000000000 +0100 +diff -urN linux.old/include/linux/netfilter_ipv4/ip_conntrack.h linux.dev/include/linux/netfilter_ipv4/ip_conntrack.h +--- linux.old/include/linux/netfilter_ipv4/ip_conntrack.h	2007-01-01 05:17:07.000000000 +0100 ++++ linux.dev/include/linux/netfilter_ipv4/ip_conntrack.h	2007-01-01 05:18:48.000000000 +0100  @@ -127,6 +127,15 @@   	/* Traversed often, so hopefully in different cacheline to top */   	/* These are my tuples; original and reply */ @@ -17,10 +17,10 @@ diff -urN linux-2.6.19.old/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6   };   struct ip_conntrack_expect -diff -urN linux-2.6.19.old/include/linux/netfilter_ipv4/ipt_layer7.h linux-2.6.19.dev/include/linux/netfilter_ipv4/ipt_layer7.h ---- linux-2.6.19.old/include/linux/netfilter_ipv4/ipt_layer7.h	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.19.dev/include/linux/netfilter_ipv4/ipt_layer7.h	2006-12-14 03:13:37.000000000 +0100 -@@ -0,0 +1,27 @@ +diff -urN linux.old/include/linux/netfilter_ipv4/ipt_layer7.h linux.dev/include/linux/netfilter_ipv4/ipt_layer7.h +--- linux.old/include/linux/netfilter_ipv4/ipt_layer7.h	1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/include/linux/netfilter_ipv4/ipt_layer7.h	2007-01-01 05:18:48.000000000 +0100 +@@ -0,0 +1,26 @@  +/*  +  By Matthew Strait <quadong@users.sf.net>, Dec 2003.  +  http://l7-filter.sf.net @@ -44,13 +44,12 @@ diff -urN linux-2.6.19.old/include/linux/netfilter_ipv4/ipt_layer7.h linux-2.6.1  +    char protocol[MAX_PROTOCOL_LEN];  +    char invert:1;  +    char pattern[MAX_PATTERN_LEN]; -+    char pkt;  +};  +  +#endif /* _IPT_LAYER7_H */ -diff -urN linux-2.6.19.old/net/ipv4/netfilter/ip_conntrack_core.c linux-2.6.19.dev/net/ipv4/netfilter/ip_conntrack_core.c ---- linux-2.6.19.old/net/ipv4/netfilter/ip_conntrack_core.c	2006-11-29 22:57:37.000000000 +0100 -+++ linux-2.6.19.dev/net/ipv4/netfilter/ip_conntrack_core.c	2006-12-14 03:13:37.000000000 +0100 +diff -urN linux.old/net/ipv4/netfilter/ip_conntrack_core.c linux.dev/net/ipv4/netfilter/ip_conntrack_core.c +--- linux.old/net/ipv4/netfilter/ip_conntrack_core.c	2007-01-01 05:17:07.000000000 +0100 ++++ linux.dev/net/ipv4/netfilter/ip_conntrack_core.c	2007-01-01 05:18:48.000000000 +0100  @@ -337,6 +337,13 @@   	 * too. */   	ip_ct_remove_expectations(ct); @@ -65,9 +64,9 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/ip_conntrack_core.c linux-2.6.19.d   	/* We overload first tuple to link into unconfirmed list. */   	if (!is_confirmed(ct)) {   		BUG_ON(list_empty(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list)); -diff -urN linux-2.6.19.old/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.6.19.dev/net/ipv4/netfilter/ip_conntrack_standalone.c ---- linux-2.6.19.old/net/ipv4/netfilter/ip_conntrack_standalone.c	2006-11-29 22:57:37.000000000 +0100 -+++ linux-2.6.19.dev/net/ipv4/netfilter/ip_conntrack_standalone.c	2006-12-14 03:13:37.000000000 +0100 +diff -urN linux.old/net/ipv4/netfilter/ip_conntrack_standalone.c linux.dev/net/ipv4/netfilter/ip_conntrack_standalone.c +--- linux.old/net/ipv4/netfilter/ip_conntrack_standalone.c	2007-01-01 05:17:07.000000000 +0100 ++++ linux.dev/net/ipv4/netfilter/ip_conntrack_standalone.c	2007-01-01 05:18:48.000000000 +0100  @@ -192,6 +192,12 @@   		return -ENOSPC;   #endif @@ -81,17 +80,16 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.   	if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use)))   		return -ENOSPC; -diff -urN linux-2.6.19.old/net/ipv4/netfilter/ipt_layer7.c linux-2.6.19.dev/net/ipv4/netfilter/ipt_layer7.c ---- linux-2.6.19.old/net/ipv4/netfilter/ipt_layer7.c	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.19.dev/net/ipv4/netfilter/ipt_layer7.c	2006-12-14 03:13:37.000000000 +0100 -@@ -0,0 +1,586 @@ +diff -urN linux.old/net/ipv4/netfilter/ipt_layer7.c linux.dev/net/ipv4/netfilter/ipt_layer7.c +--- linux.old/net/ipv4/netfilter/ipt_layer7.c	1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/net/ipv4/netfilter/ipt_layer7.c	2007-01-01 05:18:48.000000000 +0100 +@@ -0,0 +1,573 @@  +/* -+  Kernel module to match application layer (OSI layer 7) -+  data in connections. ++  Kernel module to match application layer (OSI layer 7) data in connections.  +  +  http://l7-filter.sf.net  + -+  By Matthew Strait and Ethan Sommer, 2003-2005. ++  By Matthew Strait and Ethan Sommer, 2003-2006.  +  +  This program is free software; you can redistribute it and/or  +  modify it under the terms of the GNU General Public License @@ -156,9 +154,9 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/ipt_layer7.c linux-2.6.19.dev/net/  +- It doesn't matter if two packets from different connections are in here at  +  the same time, because they don't share any data.  + -+- It _does_ matter if two packets from the same connection are here at the same -+  time.  In this case, we have to protect the conntracks and the list of -+  compiled patterns. ++- It _does_ matter if two packets from the same connection (or one from a ++  master and one from its child) are here at the same time.  In this case, ++  we have to protect the conntracks and the list of compiled patterns.  +*/  +DEFINE_RWLOCK(ct_lock);  +DEFINE_SPINLOCK(list_lock); @@ -337,9 +335,8 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/ipt_layer7.c linux-2.6.19.dev/net/  +		if(!master_conntrack->layer7.app_proto) {  +			char * f = friendly_print(master_conntrack->layer7.app_data);  +			char * g = hex_print(master_conntrack->layer7.app_data); -+			DPRINTK("\nl7-filter gave up after %d bytes (%llu packets):\n%s\n", -+				strlen(f), -+				TOTAL_PACKETS, f); ++			DPRINTK("\nl7-filter gave up after %d bytes (%d packets):\n%s\n", ++				strlen(f), TOTAL_PACKETS, f);  +			kfree(f);  +			DPRINTK("In hex: %s\n", g);  +			kfree(g); @@ -385,50 +382,52 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/ipt_layer7.c linux-2.6.19.dev/net/  +	}  +}  + -+static int add_datastr(char *target, int offset, char *app_data, int len) ++/* add the new app data to the conntrack.  Return number of bytes added. */ ++static int add_data(struct ip_conntrack * master_conntrack, ++			char * app_data, int appdatalen)  +{  +	int length = 0, i; ++	int oldlength = master_conntrack->layer7.app_data_len; ++ ++	// This is a fix for a race condition by Deti Fliegl. However, I'm not  ++	// clear on whether the race condition exists or whether this really  ++	// fixes it.  I might just be being dense... Anyway, if it's not really  ++	// a fix, all it does is waste a very small amount of time. ++	if(!master_conntrack->layer7.app_data) return 0;  +  +	/* Strip nulls. Make everything lower case (our regex lib doesn't  +	do case insensitivity).  Add it to the end of the current data. */ -+	for(i = 0; i < maxdatalen-offset-1 && i < len; i++) { ++	for(i = 0; i < maxdatalen-oldlength-1 && ++		   i < appdatalen; i++) {  +		if(app_data[i] != '\0') { -+			target[length+offset] = ++			master_conntrack->layer7.app_data[length+oldlength] =  +				/* the kernel version of tolower mungs 'upper ascii' */  +				isascii(app_data[i])? tolower(app_data[i]) : app_data[i];  +			length++;  +		}  +	} -+	target[length+offset] = '\0'; -+ -+	return length; -+}  + -+/* add the new app data to the conntrack.  Return number of bytes added. */ -+static int add_data(struct ip_conntrack * master_conntrack, -+			char * app_data, int appdatalen) -+{ -+	int length; -+ -+	length = add_datastr(master_conntrack->layer7.app_data, master_conntrack->layer7.app_data_len, app_data, appdatalen); -+	master_conntrack->layer7.app_data_len += length; ++	master_conntrack->layer7.app_data[length+oldlength] = '\0'; ++	master_conntrack->layer7.app_data_len = length + oldlength;  +  +	return length;  +}  +  +/* Returns true on match and false otherwise.  */ -+static int match(const struct sk_buff *skb_t, 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) ++static int match(const struct sk_buff *skbin, ++	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)  +{ ++	/* sidestep const without getting a compiler warning... */ ++	struct sk_buff * skb = (struct sk_buff *)skbin;  ++  +	struct ipt_layer7_info * info = (struct ipt_layer7_info *)matchinfo;  +	enum ip_conntrack_info master_ctinfo, ctinfo;  +	struct ip_conntrack *master_conntrack, *conntrack; -+	unsigned char *app_data, *tmp_data; ++	unsigned char * app_data;  +	unsigned int pattern_result, appdatalen;  +	regexp * comppattern; -+	struct sk_buff *skb = skb_t; /* to leave warning - FIXME */  +  +	if(!can_handle(skb)){  +		DPRINTK("layer7: This is some protocol I can't handle.\n"); @@ -449,8 +448,8 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/ipt_layer7.c linux-2.6.19.dev/net/  +		master_conntrack = master_ct(master_conntrack);  +  +	/* if we've classified it or seen too many packets */ -+	if(!info->pkt && (TOTAL_PACKETS > num_packets || -+		master_conntrack->layer7.app_proto)) { ++	if(TOTAL_PACKETS > num_packets || ++	   master_conntrack->layer7.app_proto) {  +  +		pattern_result = match_no_append(conntrack, master_conntrack, ctinfo, master_ctinfo, info);  + @@ -481,23 +480,6 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/ipt_layer7.c linux-2.6.19.dev/net/  +	comppattern = compile_and_cache(info->pattern, info->protocol);  +	spin_unlock_bh(&list_lock);  + -+	if (info->pkt) { -+		tmp_data = kmalloc(maxdatalen, GFP_ATOMIC); -+		if(!tmp_data){ -+			if (net_ratelimit()) -+				printk(KERN_ERR "layer7: out of memory in match, bailing.\n"); -+			return info->invert; -+		} -+ -+		tmp_data[0] = '\0'; -+		add_datastr(tmp_data, 0, app_data, appdatalen); -+		pattern_result = ((comppattern && regexec(comppattern, tmp_data)) ? 1 : 0); -+		kfree(tmp_data); -+		tmp_data = NULL; -+ -+		return (pattern_result ^ info->invert); -+	} -+  +	/* On the first packet of a connection, allocate space for app data */  +	write_lock(&ct_lock);  +	if(TOTAL_PACKETS == 1 && !skb->cb[0] && !master_conntrack->layer7.app_data) { @@ -533,6 +515,7 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/ipt_layer7.c linux-2.6.19.dev/net/  +  +	/* If looking for "unknown", then never match.  "Unknown" means that  +	we've given up; we're still trying with these packets. */ ++	read_lock(&ct_lock);  +	if(!strcmp(info->protocol, "unknown")) {  +		pattern_result = 0;  +	/* If the regexp failed to compile, don't bother running it */ @@ -540,6 +523,7 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/ipt_layer7.c linux-2.6.19.dev/net/  +		DPRINTK("layer7: matched %s\n", info->protocol);  +		pattern_result = 1;  +	} else pattern_result = 0; ++	read_unlock(&ct_lock);  +  +	if(pattern_result) {  +		write_lock(&ct_lock); @@ -563,7 +547,7 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/ipt_layer7.c linux-2.6.19.dev/net/  +static struct ipt_match layer7_match = {  +	.name = "layer7",  +	.match = &match, -+	.matchsize = sizeof(struct ipt_layer7_info), ++	.matchsize  = sizeof(struct ipt_layer7_info),  +	.me = THIS_MODULE  +};  + @@ -647,8 +631,10 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/ipt_layer7.c linux-2.6.19.dev/net/  +	remove_proc_entry("layer7_numpackets", proc_net);  +}  + -+static int __init init(void) ++static int __init ipt_layer7_init(void)  +{ ++	need_conntrack(); ++  +	layer7_init_proc();  +	if(maxdatalen < 1) {  +		printk(KERN_WARNING "layer7: maxdatalen can't be < 1, using 1\n"); @@ -663,20 +649,20 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/ipt_layer7.c linux-2.6.19.dev/net/  +	return ipt_register_match(&layer7_match);  +}  + -+static void __exit fini(void) ++static void __exit ipt_layer7_fini(void)  +{  +	layer7_cleanup_proc();  +	ipt_unregister_match(&layer7_match);  +}  + -+module_init(init); -+module_exit(fini); -diff -urN linux-2.6.19.old/net/ipv4/netfilter/Kconfig linux-2.6.19.dev/net/ipv4/netfilter/Kconfig ---- linux-2.6.19.old/net/ipv4/netfilter/Kconfig	2006-11-29 22:57:37.000000000 +0100 -+++ linux-2.6.19.dev/net/ipv4/netfilter/Kconfig	2006-12-14 03:13:37.000000000 +0100 -@@ -329,6 +329,24 @@ - 	  destination IP' or `500pps from any given source IP'  with a single - 	  IPtables rule. ++module_init(ipt_layer7_init); ++module_exit(ipt_layer7_fini); +diff -urN linux.old/net/ipv4/netfilter/Kconfig linux.dev/net/ipv4/netfilter/Kconfig +--- linux.old/net/ipv4/netfilter/Kconfig	2007-01-01 05:17:07.000000000 +0100 ++++ linux.dev/net/ipv4/netfilter/Kconfig	2007-01-01 05:18:48.000000000 +0100 +@@ -248,6 +248,24 @@ +  + 	  To compile it as a module, choose M here.  If unsure, say N.  +config IP_NF_MATCH_LAYER7  +	tristate "Layer 7 match support (EXPERIMENTAL)" @@ -696,12 +682,12 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/Kconfig linux-2.6.19.dev/net/ipv4/  +	help  +	  Say Y to get lots of debugging output.  + - # `filter', generic and specific targets - config IP_NF_FILTER - 	tristate "Packet filtering" -diff -urN linux-2.6.19.old/net/ipv4/netfilter/Makefile linux-2.6.19.dev/net/ipv4/netfilter/Makefile ---- linux-2.6.19.old/net/ipv4/netfilter/Makefile	2006-11-29 22:57:37.000000000 +0100 -+++ linux-2.6.19.dev/net/ipv4/netfilter/Makefile	2006-12-14 03:13:37.000000000 +0100 + config IP_NF_MATCH_TOS + 	tristate "TOS match support" + 	depends on IP_NF_IPTABLES +diff -urN linux.old/net/ipv4/netfilter/Makefile linux.dev/net/ipv4/netfilter/Makefile +--- linux.old/net/ipv4/netfilter/Makefile	2007-01-01 05:17:07.000000000 +0100 ++++ linux.dev/net/ipv4/netfilter/Makefile	2007-01-01 05:18:48.000000000 +0100  @@ -63,6 +63,8 @@   obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o   obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o @@ -711,10 +697,10 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/Makefile linux-2.6.19.dev/net/ipv4   # targets   obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o   obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o -diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/net/ipv4/netfilter/regexp/regexp.c ---- linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.19.dev/net/ipv4/netfilter/regexp/regexp.c	2006-12-14 03:13:37.000000000 +0100 -@@ -0,0 +1,1195 @@ +diff -urN linux.old/net/ipv4/netfilter/regexp/regexp.c linux.dev/net/ipv4/netfilter/regexp/regexp.c +--- linux.old/net/ipv4/netfilter/regexp/regexp.c	1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/net/ipv4/netfilter/regexp/regexp.c	2007-01-01 05:18:48.000000000 +0100 +@@ -0,0 +1,1197 @@  +/*  + * regcomp and regexec -- regsub and regerror are elsewhere  + * @(#)regexp.c	1.3 of 18 April 87 @@ -881,11 +867,17 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +/*  + * Global work variables for regcomp().  + */ -+static char *regparse;		/* Input-scan pointer. */ -+static int regnpar;		/* () count. */ -+static char regdummy; -+static char *regcode;		/* Code-emit pointer; ®dummy = don't. */ -+static long regsize;		/* Code size. */ ++struct match_globals { ++char *reginput;		/* String-input pointer. */ ++char *regbol;		/* Beginning of input, for ^ check. */ ++char **regstartp;	/* Pointer to startp array. */ ++char **regendp;		/* Ditto for endp. */ ++char *regparse;		/* Input-scan pointer. */ ++int regnpar;		/* () count. */ ++char regdummy; ++char *regcode;		/* Code-emit pointer; ®dummy = don't. */ ++long regsize;		/* Code size. */ ++};  +  +/*  + * Forward declarations for regcomp()'s friends. @@ -893,16 +885,16 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +#ifndef STATIC  +#define	STATIC	static  +#endif -+STATIC char *reg(int paren,int *flagp); -+STATIC char *regbranch(int *flagp); -+STATIC char *regpiece(int *flagp); -+STATIC char *regatom(int *flagp); -+STATIC char *regnode(char op); -+STATIC char *regnext(char *p); -+STATIC void regc(char b); -+STATIC void reginsert(char op, char *opnd); -+STATIC void regtail(char *p, char *val); -+STATIC void regoptail(char *p, char *val); ++STATIC char *reg(struct match_globals *g, int paren,int *flagp); ++STATIC char *regbranch(struct match_globals *g, int *flagp); ++STATIC char *regpiece(struct match_globals *g, int *flagp); ++STATIC char *regatom(struct match_globals *g, int *flagp); ++STATIC char *regnode(struct match_globals *g, char op); ++STATIC char *regnext(struct match_globals *g, char *p); ++STATIC void regc(struct match_globals *g, char b); ++STATIC void reginsert(struct match_globals *g, char op, char *opnd); ++STATIC void regtail(struct match_globals *g, char *p, char *val); ++STATIC void regoptail(struct match_globals *g, char *p, char *val);  +  +  +__kernel_size_t my_strcspn(const char *s1,const char *s2) @@ -944,6 +936,8 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +	register char *longest;  +	register int len;  +	int flags; ++	struct match_globals g; ++	  +	/* commented out by ethan  +	   extern char *malloc();  +	*/ @@ -952,30 +946,30 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +		FAIL("NULL argument");  +  +	/* First pass: determine size, legality. */ -+	regparse = exp; -+	regnpar = 1; -+	regsize = 0L; -+	regcode = ®dummy; -+	regc(MAGIC); -+	if (reg(0, &flags) == NULL) ++	g.regparse = exp; ++	g.regnpar = 1; ++	g.regsize = 0L; ++	g.regcode = &g.regdummy; ++	regc(&g, MAGIC); ++	if (reg(&g, 0, &flags) == NULL)  +		return(NULL);  +  +	/* Small enough for pointer-storage convention? */ -+	if (regsize >= 32767L)		/* Probably could be 65535L. */ ++	if (g.regsize >= 32767L)		/* Probably could be 65535L. */  +		FAIL("regexp too big");  +  +	/* Allocate space. */ -+	*patternsize=sizeof(regexp) + (unsigned)regsize; -+	r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize); ++	*patternsize=sizeof(regexp) + (unsigned)g.regsize; ++	r = (regexp *)malloc(sizeof(regexp) + (unsigned)g.regsize);  +	if (r == NULL)  +		FAIL("out of space");  +  +	/* Second pass: emit code. */ -+	regparse = exp; -+	regnpar = 1; -+	regcode = r->program; -+	regc(MAGIC); -+	if (reg(0, &flags) == NULL) ++	g.regparse = exp; ++	g.regnpar = 1; ++	g.regcode = r->program; ++	regc(&g, MAGIC); ++	if (reg(&g, 0, &flags) == NULL)  +		return(NULL);  +  +	/* Dig out information for optimizations. */ @@ -984,7 +978,7 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +	r->regmust = NULL;  +	r->regmlen = 0;  +	scan = r->program+1;			/* First BRANCH. */ -+	if (OP(regnext(scan)) == END) {		/* Only one top-level choice. */ ++	if (OP(regnext(&g, scan)) == END) {		/* Only one top-level choice. */  +		scan = OPERAND(scan);  +  +		/* Starting-point info. */ @@ -1004,7 +998,7 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +		if (flags&SPSTART) {  +			longest = NULL;  +			len = 0; -+			for (; scan != NULL; scan = regnext(scan)) ++			for (; scan != NULL; scan = regnext(&g, scan))  +				if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {  +					longest = OPERAND(scan);  +					len = strlen(OPERAND(scan)); @@ -1027,7 +1021,7 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  + * follows makes it hard to avoid.  + */  +static char * -+reg(int paren, int *flagp /* Parenthesized? */ ) ++reg(struct match_globals *g, int paren, int *flagp /* Parenthesized? */ )  +{  +	register char *ret;  +	register char *br; @@ -1039,49 +1033,49 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +  +	/* Make an OPEN node, if parenthesized. */  +	if (paren) { -+		if (regnpar >= NSUBEXP) ++		if (g->regnpar >= NSUBEXP)  +			FAIL("too many ()"); -+		parno = regnpar; -+		regnpar++; -+		ret = regnode(OPEN+parno); ++		parno = g->regnpar; ++		g->regnpar++; ++		ret = regnode(g, OPEN+parno);  +	} else  +		ret = NULL;  +  +	/* Pick up the branches, linking them together. */ -+	br = regbranch(&flags); ++	br = regbranch(g, &flags);  +	if (br == NULL)  +		return(NULL);  +	if (ret != NULL) -+		regtail(ret, br);	/* OPEN -> first. */ ++		regtail(g, ret, br);	/* OPEN -> first. */  +	else  +		ret = br;  +	if (!(flags&HASWIDTH))  +		*flagp &= ~HASWIDTH;  +	*flagp |= flags&SPSTART; -+	while (*regparse == '|') { -+		regparse++; -+		br = regbranch(&flags); ++	while (*g->regparse == '|') { ++		g->regparse++; ++		br = regbranch(g, &flags);  +		if (br == NULL)  +			return(NULL); -+		regtail(ret, br);	/* BRANCH -> BRANCH. */ ++		regtail(g, ret, br);	/* BRANCH -> BRANCH. */  +		if (!(flags&HASWIDTH))  +			*flagp &= ~HASWIDTH;  +		*flagp |= flags&SPSTART;  +	}  +  +	/* Make a closing node, and hook it on the end. */ -+	ender = regnode((paren) ? CLOSE+parno : END); -+	regtail(ret, ender); ++	ender = regnode(g, (paren) ? CLOSE+parno : END);	 ++	regtail(g, ret, ender);  +  +	/* Hook the tails of the branches to the closing node. */ -+	for (br = ret; br != NULL; br = regnext(br)) -+		regoptail(br, ender); ++	for (br = ret; br != NULL; br = regnext(g, br)) ++		regoptail(g, br, ender);  +  +	/* Check for proper termination. */ -+	if (paren && *regparse++ != ')') { ++	if (paren && *g->regparse++ != ')') {  +		FAIL("unmatched ()"); -+	} else if (!paren && *regparse != '\0') { -+		if (*regparse == ')') { ++	} else if (!paren && *g->regparse != '\0') { ++		if (*g->regparse == ')') {  +			FAIL("unmatched ()");  +		} else  +			FAIL("junk on end");	/* "Can't happen". */ @@ -1097,7 +1091,7 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  + * Implements the concatenation operator.  + */  +static char * -+regbranch(int *flagp) ++regbranch(struct match_globals *g, int *flagp)  +{  +	register char *ret;  +	register char *chain; @@ -1106,21 +1100,21 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +  +	*flagp = WORST;		/* Tentatively. */  + -+	ret = regnode(BRANCH); ++	ret = regnode(g, BRANCH);  +	chain = NULL; -+	while (*regparse != '\0' && *regparse != '|' && *regparse != ')') { -+		latest = regpiece(&flags); ++	while (*g->regparse != '\0' && *g->regparse != '|' && *g->regparse != ')') { ++		latest = regpiece(g, &flags);  +		if (latest == NULL)  +			return(NULL);  +		*flagp |= flags&HASWIDTH;  +		if (chain == NULL)	/* First piece. */  +			*flagp |= flags&SPSTART;  +		else -+			regtail(chain, latest); ++			regtail(g, chain, latest);  +		chain = latest;  +	}  +	if (chain == NULL)	/* Loop ran zero times. */ -+		(void) regnode(NOTHING); ++		(void) regnode(g, NOTHING);  +  +	return(ret);  +} @@ -1135,18 +1129,18 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  + * endmarker role is not redundant.  + */  +static char * -+regpiece(int *flagp) ++regpiece(struct match_globals *g, int *flagp)  +{  +	register char *ret;  +	register char op;  +	register char *next;  +	int flags;  + -+	ret = regatom(&flags); ++	ret = regatom(g, &flags);  +	if (ret == NULL)  +		return(NULL);  + -+	op = *regparse; ++	op = *g->regparse;  +	if (!ISMULT(op)) {  +		*flagp = flags;  +		return(ret); @@ -1157,33 +1151,33 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +	*flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);  +  +	if (op == '*' && (flags&SIMPLE)) -+		reginsert(STAR, ret); ++		reginsert(g, STAR, ret);  +	else if (op == '*') {  +		/* Emit x* as (x&|), where & means "self". */ -+		reginsert(BRANCH, ret);			/* Either x */ -+		regoptail(ret, regnode(BACK));		/* and loop */ -+		regoptail(ret, ret);			/* back */ -+		regtail(ret, regnode(BRANCH));		/* or */ -+		regtail(ret, regnode(NOTHING));		/* null. */ ++		reginsert(g, BRANCH, ret);			/* Either x */ ++		regoptail(g, ret, regnode(g, BACK));		/* and loop */ ++		regoptail(g, ret, ret);			/* back */ ++		regtail(g, ret, regnode(g, BRANCH));		/* or */ ++		regtail(g, ret, regnode(g, NOTHING));		/* null. */  +	} else if (op == '+' && (flags&SIMPLE)) -+		reginsert(PLUS, ret); ++		reginsert(g, PLUS, ret);  +	else if (op == '+') {  +		/* Emit x+ as x(&|), where & means "self". */ -+		next = regnode(BRANCH);			/* Either */ -+		regtail(ret, next); -+		regtail(regnode(BACK), ret);		/* loop back */ -+		regtail(next, regnode(BRANCH));		/* or */ -+		regtail(ret, regnode(NOTHING));		/* null. */ ++		next = regnode(g, BRANCH);			/* Either */ ++		regtail(g, ret, next); ++		regtail(g, regnode(g, BACK), ret);		/* loop back */ ++		regtail(g, next, regnode(g, BRANCH));		/* or */ ++		regtail(g, ret, regnode(g, NOTHING));		/* null. */  +	} else if (op == '?') {  +		/* Emit x? as (x|) */ -+		reginsert(BRANCH, ret);			/* Either x */ -+		regtail(ret, regnode(BRANCH));		/* or */ -+		next = regnode(NOTHING);		/* null. */ -+		regtail(ret, next); -+		regoptail(ret, next); ++		reginsert(g, BRANCH, ret);			/* Either x */ ++		regtail(g, ret, regnode(g, BRANCH));		/* or */ ++		next = regnode(g, NOTHING);		/* null. */ ++		regtail(g, ret, next); ++		regoptail(g, ret, next);  +	} -+	regparse++; -+	if (ISMULT(*regparse)) ++	g->regparse++; ++	if (ISMULT(*g->regparse))  +		FAIL("nested *?+");  +  +	return(ret); @@ -1198,61 +1192,61 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  + * separate node; the code is simpler that way and it's not worth fixing.  + */  +static char * -+regatom(int *flagp) ++regatom(struct match_globals *g, int *flagp)  +{  +	register char *ret;  +	int flags;  +  +	*flagp = WORST;		/* Tentatively. */  + -+	switch (*regparse++) { ++	switch (*g->regparse++) {  +	case '^': -+		ret = regnode(BOL); ++		ret = regnode(g, BOL);  +		break;  +	case '$': -+		ret = regnode(EOL); ++		ret = regnode(g, EOL);  +		break;  +	case '.': -+		ret = regnode(ANY); ++		ret = regnode(g, ANY);  +		*flagp |= HASWIDTH|SIMPLE;  +		break;  +	case '[': {  +			register int class;  +			register int classend;  + -+			if (*regparse == '^') {	/* Complement of range. */ -+				ret = regnode(ANYBUT); -+				regparse++; ++			if (*g->regparse == '^') {	/* Complement of range. */ ++				ret = regnode(g, ANYBUT); ++				g->regparse++;  +			} else -+				ret = regnode(ANYOF); -+			if (*regparse == ']' || *regparse == '-') -+				regc(*regparse++); -+			while (*regparse != '\0' && *regparse != ']') { -+				if (*regparse == '-') { -+					regparse++; -+					if (*regparse == ']' || *regparse == '\0') -+						regc('-'); ++				ret = regnode(g, ANYOF); ++			if (*g->regparse == ']' || *g->regparse == '-') ++				regc(g, *g->regparse++); ++			while (*g->regparse != '\0' && *g->regparse != ']') { ++				if (*g->regparse == '-') { ++					g->regparse++; ++					if (*g->regparse == ']' || *g->regparse == '\0') ++						regc(g, '-');  +					else { -+						class = UCHARAT(regparse-2)+1; -+						classend = UCHARAT(regparse); ++						class = UCHARAT(g->regparse-2)+1; ++						classend = UCHARAT(g->regparse);  +						if (class > classend+1)  +							FAIL("invalid [] range");  +						for (; class <= classend; class++) -+							regc(class); -+						regparse++; ++							regc(g, class); ++						g->regparse++;  +					}  +				} else -+					regc(*regparse++); ++					regc(g, *g->regparse++);  +			} -+			regc('\0'); -+			if (*regparse != ']') ++			regc(g, '\0'); ++			if (*g->regparse != ']')  +				FAIL("unmatched []"); -+			regparse++; ++			g->regparse++;  +			*flagp |= HASWIDTH|SIMPLE;  +		}  +		break;  +	case '(': -+		ret = reg(1, &flags); ++		ret = reg(g, 1, &flags);  +		if (ret == NULL)  +			return(NULL);  +		*flagp |= flags&(HASWIDTH|SPSTART); @@ -1268,33 +1262,33 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +		FAIL("?+* follows nothing");  +		break;  +	case '\\': -+		if (*regparse == '\0') ++		if (*g->regparse == '\0')  +			FAIL("trailing \\"); -+		ret = regnode(EXACTLY); -+		regc(*regparse++); -+		regc('\0'); ++		ret = regnode(g, EXACTLY); ++		regc(g, *g->regparse++); ++		regc(g, '\0');  +		*flagp |= HASWIDTH|SIMPLE;  +		break;  +	default: {  +			register int len;  +			register char ender;  + -+			regparse--; -+			len = my_strcspn((const char *)regparse, (const char *)META); ++			g->regparse--; ++			len = my_strcspn((const char *)g->regparse, (const char *)META);  +			if (len <= 0)  +				FAIL("internal disaster"); -+			ender = *(regparse+len); ++			ender = *(g->regparse+len);  +			if (len > 1 && ISMULT(ender))  +				len--;		/* Back off clear of ?+* operand. */  +			*flagp |= HASWIDTH;  +			if (len == 1)  +				*flagp |= SIMPLE; -+			ret = regnode(EXACTLY); ++			ret = regnode(g, EXACTLY);  +			while (len > 0) { -+				regc(*regparse++); ++				regc(g, *g->regparse++);  +				len--;  +			} -+			regc('\0'); ++			regc(g, '\0');  +		}  +		break;  +	} @@ -1306,14 +1300,14 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  + - regnode - emit a node  + */  +static char *			/* Location. */ -+regnode(char op) ++regnode(struct match_globals *g, char op)  +{  +	register char *ret;  +	register char *ptr;  + -+	ret = regcode; -+	if (ret == ®dummy) { -+		regsize += 3; ++	ret = g->regcode; ++	if (ret == &g->regdummy) { ++		g->regsize += 3;  +		return(ret);  +	}  + @@ -1321,7 +1315,7 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +	*ptr++ = op;  +	*ptr++ = '\0';		/* Null "next" pointer. */  +	*ptr++ = '\0'; -+	regcode = ptr; ++	g->regcode = ptr;  +  +	return(ret);  +} @@ -1330,12 +1324,12 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  + - regc - emit (if appropriate) a byte of code  + */  +static void -+regc(char b) ++regc(struct match_globals *g, char b)  +{ -+	if (regcode != ®dummy) -+		*regcode++ = b; ++	if (g->regcode != &g->regdummy) ++		*g->regcode++ = b;  +	else -+		regsize++; ++		g->regsize++;  +}  +  +/* @@ -1344,20 +1338,20 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  + * Means relocating the operand.  + */  +static void -+reginsert(char op, char* opnd) ++reginsert(struct match_globals *g, char op, char* opnd)  +{  +	register char *src;  +	register char *dst;  +	register char *place;  + -+	if (regcode == ®dummy) { -+		regsize += 3; ++	if (g->regcode == &g->regdummy) { ++		g->regsize += 3;  +		return;  +	}  + -+	src = regcode; -+	regcode += 3; -+	dst = regcode; ++	src = g->regcode; ++	g->regcode += 3; ++	dst = g->regcode;  +	while (src > opnd)  +		*--dst = *--src;  + @@ -1371,19 +1365,19 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  + - regtail - set the next-pointer at the end of a node chain  + */  +static void -+regtail(char *p, char *val) ++regtail(struct match_globals *g, char *p, char *val)  +{  +	register char *scan;  +	register char *temp;  +	register int offset;  + -+	if (p == ®dummy) ++	if (p == &g->regdummy)  +		return;  +  +	/* Find last node. */  +	scan = p;  +	for (;;) { -+		temp = regnext(scan); ++		temp = regnext(g, scan);  +		if (temp == NULL)  +			break;  +		scan = temp; @@ -1401,32 +1395,25 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  + - regoptail - regtail on operand of first argument; nop if operandless  + */  +static void -+regoptail(char *p, char *val) ++regoptail(struct match_globals *g, char *p, char *val)  +{  +	/* "Operandless" and "op != BRANCH" are synonymous in practice. */ -+	if (p == NULL || p == ®dummy || OP(p) != BRANCH) ++	if (p == NULL || p == &g->regdummy || OP(p) != BRANCH)  +		return; -+	regtail(OPERAND(p), val); ++	regtail(g, OPERAND(p), val);  +}  +  +/*  + * regexec and friends  + */  + -+/* -+ * Global work variables for regexec(). -+ */ -+static char *reginput;		/* String-input pointer. */ -+static char *regbol;		/* Beginning of input, for ^ check. */ -+static char **regstartp;	/* Pointer to startp array. */ -+static char **regendp;		/* Ditto for endp. */  +  +/*  + * Forwards.  + */ -+STATIC int regtry(regexp *prog, char *string); -+STATIC int regmatch(char *prog); -+STATIC int regrepeat(char *p); ++STATIC int regtry(struct match_globals *g, regexp *prog, char *string); ++STATIC int regmatch(struct match_globals *g, char *prog); ++STATIC int regrepeat(struct match_globals *g, char *p);  +  +#ifdef DEBUG  +int regnarrate = 0; @@ -1441,6 +1428,7 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +regexec(regexp *prog, char *string)  +{  +	register char *s; ++	struct match_globals g;  +  +	/* Be paranoid... */  +	if (prog == NULL || string == NULL) { @@ -1467,25 +1455,25 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +	}  +  +	/* Mark beginning of line for ^ . */ -+	regbol = string; ++	g.regbol = string;  +  +	/* Simplest case:  anchored match need be tried only once. */  +	if (prog->reganch) -+		return(regtry(prog, string)); ++		return(regtry(&g, prog, string));  +  +	/* Messy cases:  unanchored match. */  +	s = string;  +	if (prog->regstart != '\0')  +		/* We know what char it must start with. */  +		while ((s = strchr(s, prog->regstart)) != NULL) { -+			if (regtry(prog, s)) ++			if (regtry(&g, prog, s))  +				return(1);  +			s++;  +		}  +	else  +		/* We don't -- general case. */  +		do { -+			if (regtry(prog, s)) ++			if (regtry(&g, prog, s))  +				return(1);  +		} while (*s++ != '\0');  + @@ -1497,15 +1485,15 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  + - regtry - try match at specific point  + */  +static int			/* 0 failure, 1 success */ -+regtry(regexp *prog, char *string) ++regtry(struct match_globals *g, regexp *prog, char *string)  +{  +	register int i;  +	register char **sp;  +	register char **ep;  + -+	reginput = string; -+	regstartp = prog->startp; -+	regendp = prog->endp; ++	g->reginput = string; ++	g->regstartp = prog->startp; ++	g->regendp = prog->endp;  +  +	sp = prog->startp;  +	ep = prog->endp; @@ -1513,9 +1501,9 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +		*sp++ = NULL;  +		*ep++ = NULL;  +	} -+	if (regmatch(prog->program + 1)) { ++	if (regmatch(g, prog->program + 1)) {  +		prog->startp[0] = string; -+		prog->endp[0] = reginput; ++		prog->endp[0] = g->reginput;  +		return(1);  +	} else  +		return(0); @@ -1532,7 +1520,7 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  + * by recursion.  + */  +static int			/* 0 failure, 1 success */ -+regmatch(char *prog) ++regmatch(struct match_globals *g, char *prog)  +{  +	register char *scan = prog; /* Current node. */  +	char *next;		    /* Next node. */ @@ -1546,21 +1534,21 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +		if (regnarrate)  +			fprintf(stderr, "%s...\n", regprop(scan));  +#endif -+		next = regnext(scan); ++		next = regnext(g, scan);  +  +		switch (OP(scan)) {  +		case BOL: -+			if (reginput != regbol) ++			if (g->reginput != g->regbol)  +				return(0);  +			break;  +		case EOL: -+			if (*reginput != '\0') ++			if (*g->reginput != '\0')  +				return(0);  +			break;  +		case ANY: -+			if (*reginput == '\0') ++			if (*g->reginput == '\0')  +				return(0); -+			reginput++; ++			g->reginput++;  +			break;  +		case EXACTLY: {  +				register int len; @@ -1568,23 +1556,23 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +  +				opnd = OPERAND(scan);  +				/* Inline the first character, for speed. */ -+				if (*opnd != *reginput) ++				if (*opnd != *g->reginput)  +					return(0);  +				len = strlen(opnd); -+				if (len > 1 && strncmp(opnd, reginput, len) != 0) ++				if (len > 1 && strncmp(opnd, g->reginput, len) != 0)  +					return(0); -+				reginput += len; ++				g->reginput += len;  +			}  +			break;  +		case ANYOF: -+			if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL) ++			if (*g->reginput == '\0' || strchr(OPERAND(scan), *g->reginput) == NULL)  +				return(0); -+			reginput++; ++			g->reginput++;  +			break;  +		case ANYBUT: -+			if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL) ++			if (*g->reginput == '\0' || strchr(OPERAND(scan), *g->reginput) != NULL)  +				return(0); -+			reginput++; ++			g->reginput++;  +			break;  +		case NOTHING:  +		case BACK: @@ -1602,16 +1590,16 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +				register char *save;  +  +				no = OP(scan) - OPEN; -+				save = reginput; ++				save = g->reginput;  + -+				if (regmatch(next)) { ++				if (regmatch(g, next)) {  +					/*  +					 * Don't set startp if some later  +					 * invocation of the same parentheses  +					 * already has.  +					 */ -+					if (regstartp[no] == NULL) -+						regstartp[no] = save; ++					if (g->regstartp[no] == NULL) ++						g->regstartp[no] = save;  +					return(1);  +				} else  +					return(0); @@ -1631,16 +1619,16 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +				register char *save;  +  +				no = OP(scan) - CLOSE; -+				save = reginput; ++				save = g->reginput;  + -+				if (regmatch(next)) { ++				if (regmatch(g, next)) {  +					/*  +					 * Don't set endp if some later  +					 * invocation of the same parentheses  +					 * already has.  +					 */ -+					if (regendp[no] == NULL) -+						regendp[no] = save; ++					if (g->regendp[no] == NULL) ++						g->regendp[no] = save;  +					return(1);  +				} else  +					return(0); @@ -1653,11 +1641,11 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +					next = OPERAND(scan);	/* Avoid recursion. */  +				else {  +					do { -+						save = reginput; -+						if (regmatch(OPERAND(scan))) ++						save = g->reginput; ++						if (regmatch(g, OPERAND(scan)))  +							return(1); -+						reginput = save; -+						scan = regnext(scan); ++						g->reginput = save; ++						scan = regnext(g, scan);  +					} while (scan != NULL && OP(scan) == BRANCH);  +					return(0);  +					/* NOTREACHED */ @@ -1679,16 +1667,16 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +				if (OP(next) == EXACTLY)  +					nextch = *OPERAND(next);  +				min = (OP(scan) == STAR) ? 0 : 1; -+				save = reginput; -+				no = regrepeat(OPERAND(scan)); ++				save = g->reginput; ++				no = regrepeat(g, OPERAND(scan));  +				while (no >= min) {  +					/* If it could work, try it. */ -+					if (nextch == '\0' || *reginput == nextch) -+						if (regmatch(next)) ++					if (nextch == '\0' || *g->reginput == nextch) ++						if (regmatch(g, next))  +							return(1);  +					/* Couldn't or didn't -- back up. */  +					no--; -+					reginput = save + no; ++					g->reginput = save + no;  +				}  +				return(0);  +			} @@ -1717,13 +1705,13 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  + - regrepeat - repeatedly match something simple, report how many  + */  +static int -+regrepeat(char *p) ++regrepeat(struct match_globals *g, char *p)  +{  +	register int count = 0;  +	register char *scan;  +	register char *opnd;  + -+	scan = reginput; ++	scan = g->reginput;  +	opnd = OPERAND(p);  +	switch (OP(p)) {  +	case ANY: @@ -1753,7 +1741,7 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +		count = 0;	/* Best compromise. */  +		break;  +	} -+	reginput = scan; ++	g->reginput = scan;  +  +	return(count);  +} @@ -1762,11 +1750,11 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  + - regnext - dig the "next" pointer out of a node  + */  +static char* -+regnext(char *p) ++regnext(struct match_globals *g, char *p)  +{  +	register int offset;  + -+	if (p == ®dummy) ++	if (p == &g->regdummy)  +		return(NULL);  +  +	offset = NEXT(p); @@ -1910,9 +1898,9 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.c linux-2.6.19.dev/n  +#endif  +  + -diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.h linux-2.6.19.dev/net/ipv4/netfilter/regexp/regexp.h ---- linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.h	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.19.dev/net/ipv4/netfilter/regexp/regexp.h	2006-12-14 03:13:37.000000000 +0100 +diff -urN linux.old/net/ipv4/netfilter/regexp/regexp.h linux.dev/net/ipv4/netfilter/regexp/regexp.h +--- linux.old/net/ipv4/netfilter/regexp/regexp.h	1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/net/ipv4/netfilter/regexp/regexp.h	2007-01-01 05:18:48.000000000 +0100  @@ -0,0 +1,41 @@  +/*  + * Definitions etc. for regexp(3) routines. @@ -1955,18 +1943,18 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regexp.h linux-2.6.19.dev/n  +void regerror(char *s);  +  +#endif -diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regmagic.h linux-2.6.19.dev/net/ipv4/netfilter/regexp/regmagic.h ---- linux-2.6.19.old/net/ipv4/netfilter/regexp/regmagic.h	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.19.dev/net/ipv4/netfilter/regexp/regmagic.h	2006-12-14 03:13:37.000000000 +0100 +diff -urN linux.old/net/ipv4/netfilter/regexp/regmagic.h linux.dev/net/ipv4/netfilter/regexp/regmagic.h +--- linux.old/net/ipv4/netfilter/regexp/regmagic.h	1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/net/ipv4/netfilter/regexp/regmagic.h	2007-01-01 05:18:48.000000000 +0100  @@ -0,0 +1,5 @@  +/*  + * The first byte of the regexp internal "program" is actually this magic  + * number; the start node begins in the second byte.  + */  +#define	MAGIC	0234 -diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regsub.c linux-2.6.19.dev/net/ipv4/netfilter/regexp/regsub.c ---- linux-2.6.19.old/net/ipv4/netfilter/regexp/regsub.c	1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.19.dev/net/ipv4/netfilter/regexp/regsub.c	2006-12-14 03:13:37.000000000 +0100 +diff -urN linux.old/net/ipv4/netfilter/regexp/regsub.c linux.dev/net/ipv4/netfilter/regexp/regsub.c +--- linux.old/net/ipv4/netfilter/regexp/regsub.c	1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/net/ipv4/netfilter/regexp/regsub.c	2007-01-01 05:18:48.000000000 +0100  @@ -0,0 +1,95 @@  +/*  + * regsub @@ -2024,7 +2012,7 @@ diff -urN linux-2.6.19.old/net/ipv4/netfilter/regexp/regsub.c linux-2.6.19.dev/n  +	register char c;  +	register int no;  +	register int len; -+ ++	  +	/* Not necessary and gcc doesn't like it -MLS */  +	/*extern char *strncpy();*/  + diff --git a/target/linux/generic-2.6/patches/101-netfilter_layer7_pktmatch.patch b/target/linux/generic-2.6/patches/101-netfilter_layer7_pktmatch.patch new file mode 100644 index 000000000..3d1e4819d --- /dev/null +++ b/target/linux/generic-2.6/patches/101-netfilter_layer7_pktmatch.patch @@ -0,0 +1,108 @@ +diff -ur linux.dev/include/linux/netfilter_ipv4/ipt_layer7.h linux.dev2/include/linux/netfilter_ipv4/ipt_layer7.h +--- linux.dev/include/linux/netfilter_ipv4/ipt_layer7.h	2007-01-01 05:18:48.000000000 +0100 ++++ linux.dev2/include/linux/netfilter_ipv4/ipt_layer7.h	2007-01-01 05:30:46.000000000 +0100 +@@ -21,6 +21,7 @@ +     char protocol[MAX_PROTOCOL_LEN]; +     char invert:1; +     char pattern[MAX_PATTERN_LEN]; ++    char pkt; + }; +  + #endif /* _IPT_LAYER7_H */ +diff -ur linux.dev/net/ipv4/netfilter/ipt_layer7.c linux.dev2/net/ipv4/netfilter/ipt_layer7.c +--- linux.dev/net/ipv4/netfilter/ipt_layer7.c	2007-01-01 05:18:48.000000000 +0100 ++++ linux.dev2/net/ipv4/netfilter/ipt_layer7.c	2007-01-01 05:30:46.000000000 +0100 +@@ -296,33 +296,34 @@ + 	} + } +  +-/* add the new app data to the conntrack.  Return number of bytes added. */ +-static int add_data(struct ip_conntrack * master_conntrack, +-			char * app_data, int appdatalen) ++static int add_datastr(char *target, int offset, char *app_data, int len) + { + 	int length = 0, i; +-	int oldlength = master_conntrack->layer7.app_data_len; +- +-	// This is a fix for a race condition by Deti Fliegl. However, I'm not  +-	// clear on whether the race condition exists or whether this really  +-	// fixes it.  I might just be being dense... Anyway, if it's not really  +-	// a fix, all it does is waste a very small amount of time. +-	if(!master_conntrack->layer7.app_data) return 0; ++	if(!target) return 0; +  + 	/* Strip nulls. Make everything lower case (our regex lib doesn't + 	do case insensitivity).  Add it to the end of the current data. */ +-	for(i = 0; i < maxdatalen-oldlength-1 && +-		   i < appdatalen; i++) { ++	for(i = 0; i < maxdatalen-offset-1 && i < len; i++) { + 		if(app_data[i] != '\0') { +-			master_conntrack->layer7.app_data[length+oldlength] = ++			target[length+offset] = + 				/* the kernel version of tolower mungs 'upper ascii' */ + 				isascii(app_data[i])? tolower(app_data[i]) : app_data[i]; + 			length++; + 		} + 	} ++	target[length+offset] = '\0'; +  +-	master_conntrack->layer7.app_data[length+oldlength] = '\0'; +-	master_conntrack->layer7.app_data_len = length + oldlength; ++	return length; ++} ++ ++/* add the new app data to the conntrack.  Return number of bytes added. */ ++static int add_data(struct ip_conntrack * master_conntrack, ++			char * app_data, int appdatalen) ++{ ++	int length; ++ ++	length = add_datastr(master_conntrack->layer7.app_data, master_conntrack->layer7.app_data_len, app_data, appdatalen); ++	master_conntrack->layer7.app_data_len += length; +  + 	return length; + } +@@ -339,7 +340,7 @@ + 	struct ipt_layer7_info * info = (struct ipt_layer7_info *)matchinfo; + 	enum ip_conntrack_info master_ctinfo, ctinfo; + 	struct ip_conntrack *master_conntrack, *conntrack; +-	unsigned char * app_data; ++	unsigned char *app_data, *tmp_data; + 	unsigned int pattern_result, appdatalen; + 	regexp * comppattern; +  +@@ -362,8 +363,8 @@ + 		master_conntrack = master_ct(master_conntrack); +  + 	/* if we've classified it or seen too many packets */ +-	if(TOTAL_PACKETS > num_packets || +-	   master_conntrack->layer7.app_proto) { ++	if(!info->pkt && (TOTAL_PACKETS > num_packets || ++		master_conntrack->layer7.app_proto)) { +  + 		pattern_result = match_no_append(conntrack, master_conntrack, ctinfo, master_ctinfo, info); +  +@@ -394,6 +395,23 @@ + 	comppattern = compile_and_cache(info->pattern, info->protocol); + 	spin_unlock_bh(&list_lock); +  ++	if (info->pkt) { ++		tmp_data = kmalloc(maxdatalen, GFP_ATOMIC); ++		if(!tmp_data){ ++			if (net_ratelimit()) ++				printk(KERN_ERR "layer7: out of memory in match, bailing.\n"); ++			return info->invert; ++		} ++ ++		tmp_data[0] = '\0'; ++		add_datastr(tmp_data, 0, app_data, appdatalen); ++		pattern_result = ((comppattern && regexec(comppattern, tmp_data)) ? 1 : 0); ++		kfree(tmp_data); ++		tmp_data = NULL; ++ ++		return (pattern_result ^ info->invert); ++	} ++ + 	/* On the first packet of a connection, allocate space for app data */ + 	write_lock(&ct_lock); + 	if(TOTAL_PACKETS == 1 && !skb->cb[0] && !master_conntrack->layer7.app_data) { diff --git a/target/linux/generic-2.6/patches/101-ipp2p_0.8.1rc1.patch b/target/linux/generic-2.6/patches/110-ipp2p_0.8.1rc1.patch index e03f4d567..e03f4d567 100644 --- a/target/linux/generic-2.6/patches/101-ipp2p_0.8.1rc1.patch +++ b/target/linux/generic-2.6/patches/110-ipp2p_0.8.1rc1.patch diff --git a/target/linux/generic-2.6/patches/102-openswan-2.4.0.kernel-2.6-natt.patch b/target/linux/generic-2.6/patches/120-openswan-2.4.0.kernel-2.6-natt.patch index 2b4238c68..2b4238c68 100644 --- a/target/linux/generic-2.6/patches/102-openswan-2.4.0.kernel-2.6-natt.patch +++ b/target/linux/generic-2.6/patches/120-openswan-2.4.0.kernel-2.6-natt.patch diff --git a/target/linux/generic-2.6/patches/103-netfilter-ipset.patch b/target/linux/generic-2.6/patches/130-netfilter-ipset.patch index 8a35d8a6b..8a35d8a6b 100644 --- a/target/linux/generic-2.6/patches/103-netfilter-ipset.patch +++ b/target/linux/generic-2.6/patches/130-netfilter-ipset.patch diff --git a/target/linux/generic-2.6/patches/105-netfilter_time.patch b/target/linux/generic-2.6/patches/140-netfilter_time.patch index d217157d7..d217157d7 100644 --- a/target/linux/generic-2.6/patches/105-netfilter_time.patch +++ b/target/linux/generic-2.6/patches/140-netfilter_time.patch diff --git a/target/linux/generic-2.6/patches/106-netfilter_imq.patch b/target/linux/generic-2.6/patches/150-netfilter_imq.patch index 559d80fbc..559d80fbc 100644 --- a/target/linux/generic-2.6/patches/106-netfilter_imq.patch +++ b/target/linux/generic-2.6/patches/150-netfilter_imq.patch diff --git a/target/linux/generic-2.6/patches/108-netfilter_route.patch b/target/linux/generic-2.6/patches/160-netfilter_route.patch index 7e8491c3e..7e8491c3e 100644 --- a/target/linux/generic-2.6/patches/108-netfilter_route.patch +++ b/target/linux/generic-2.6/patches/160-netfilter_route.patch | 
