--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
-@@ -749,6 +749,27 @@
+@@ -749,6 +749,27 @@ config NETFILTER_XT_MATCH_STATE
To compile it as a module, choose M here. If unsure, say N.
depends on NETFILTER_XTABLES
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
-@@ -78,6 +78,7 @@
+@@ -78,6 +78,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST)
obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
+
+/* Use instead of regcomp. As we expect to be seeing the same regexps over and
+over again, it make sense to cache the results. */
-+static regexp * compile_and_cache(const char * regex_string,
++static regexp * compile_and_cache(const char * regex_string,
+ const char * protocol)
+{
+ struct pattern_cache * node = first_pattern_cache;
+ if ( !node->pattern ) {
+ if (net_ratelimit())
+ printk(KERN_ERR "layer7: Error compiling regexp "
-+ "\"%s\" (%s)\n",
++ "\"%s\" (%s)\n",
+ regex_string, protocol);
+ /* pattern is now cached as NULL, so we won't try again. */
+ }
+}
+
+/* handles whether there's a match when we aren't appending data anymore */
-+static int match_no_append(struct nf_conn * conntrack,
-+ struct nf_conn * master_conntrack,
++static int match_no_append(struct nf_conn * conntrack,
++ struct nf_conn * master_conntrack,
+ enum ip_conntrack_info ctinfo,
+ enum ip_conntrack_info master_ctinfo,
+ const struct xt_layer7_info * info)
+
+ #ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
+ if(!master_conntrack->layer7.app_proto) {
-+ char * f =
++ char * f =
+ friendly_print(master_conntrack->layer7.app_data);
-+ char * g =
++ char * g =
+ hex_print(master_conntrack->layer7.app_data);
+ DPRINTK("\nl7-filter gave up after %d bytes "
+ "(%d packets):\n%s\n",
+ if(master_conntrack->layer7.app_proto){
+ /* Here child connections set their .app_proto (for /proc) */
+ if(!conntrack->layer7.app_proto) {
-+ conntrack->layer7.app_proto =
-+ kmalloc(strlen(master_conntrack->layer7.app_proto)+1,
++ conntrack->layer7.app_proto =
++ kmalloc(strlen(master_conntrack->layer7.app_proto)+1,
+ GFP_ATOMIC);
+ if(!conntrack->layer7.app_proto){
+ if (net_ratelimit())
+ "bailing.\n");
+ return 1;
+ }
-+ strcpy(conntrack->layer7.app_proto,
++ strcpy(conntrack->layer7.app_proto,
+ master_conntrack->layer7.app_proto);
+ }
+
-+ return (!strcmp(master_conntrack->layer7.app_proto,
++ return (!strcmp(master_conntrack->layer7.app_proto,
+ info->protocol));
+ }
+ else {
+ /* If not classified, set to "unknown" to distinguish from
+ connections that are still being tested. */
-+ master_conntrack->layer7.app_proto =
++ master_conntrack->layer7.app_proto =
+ kmalloc(strlen("unknown")+1, GFP_ATOMIC);
+ if(!master_conntrack->layer7.app_proto){
+ if (net_ratelimit())
+ 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
++ /* 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(app_data[i] != '\0') {
+ /* the kernel version of tolower mungs 'upper ascii' */
+ master_conntrack->layer7.app_data[length+oldlength] =
-+ isascii(app_data[i])?
++ isascii(app_data[i])?
+ tolower(app_data[i]) : app_data[i];
+ length++;
+ }
+ bool *hotdrop)
+{
+ /* sidestep const without getting a compiler warning... */
-+ struct sk_buff * skb = (struct sk_buff *)skbin;
++ struct sk_buff * skb = (struct sk_buff *)skbin;
+
+ const struct xt_layer7_info * info = matchinfo;
+ enum ip_conntrack_info master_ctinfo, ctinfo;
+ if(TOTAL_PACKETS > num_packets ||
+ master_conntrack->layer7.app_proto) {
+
-+ pattern_result = match_no_append(conntrack, master_conntrack,
++ pattern_result = match_no_append(conntrack, master_conntrack,
+ ctinfo, master_ctinfo, info);
+
-+ /* skb->cb[0] == seen. Don't do things twice if there are
-+ multiple l7 rules. I'm not sure that using cb for this purpose
-+ is correct, even though it says "put your private variables
++ /* skb->cb[0] == seen. Don't do things twice if there are
++ multiple l7 rules. I'm not sure that using cb for this purpose
++ is correct, even though it says "put your private variables
+ there". But it doesn't look like it is being used for anything
+ else in the skbs that make it here. */
+ skb->cb[0] = 1; /* marking it seen here's probably irrelevant */
+ comppattern = compile_and_cache(info->pattern, info->protocol);
+
+ /* On the first packet of a connection, allocate space for app data */
-+ if(TOTAL_PACKETS == 1 && !skb->cb[0] &&
++ if(TOTAL_PACKETS == 1 && !skb->cb[0] &&
+ !master_conntrack->layer7.app_data){
-+ master_conntrack->layer7.app_data =
++ master_conntrack->layer7.app_data =
+ kmalloc(maxdatalen, GFP_ATOMIC);
+ if(!master_conntrack->layer7.app_data){
+ if (net_ratelimit())
+ DPRINTK("layer7: matched unset: not yet classified "
+ "(%d/%d packets)\n", TOTAL_PACKETS, num_packets);
+ /* If the regexp failed to compile, don't bother running it */
-+ } else if(comppattern &&
++ } else if(comppattern &&
+ regexec(comppattern, master_conntrack->layer7.app_data)){
+ DPRINTK("layer7: matched %s\n", info->protocol);
+ pattern_result = 1;
+ } else pattern_result = 0;
+
+ if(pattern_result == 1) {
-+ master_conntrack->layer7.app_proto =
++ master_conntrack->layer7.app_proto =
+ kmalloc(strlen(info->protocol)+1, GFP_ATOMIC);
+ if(!master_conntrack->layer7.app_proto){
+ if (net_ratelimit())
+ register int len;
+ int flags;
+ struct match_globals g;
-+
++
+ /* commented out by ethan
+ extern char *malloc();
+ */
+ }
+
+ /* Make a closing node, and hook it on the end. */
-+ ender = regnode(g, (paren) ? CLOSE+parno : END);
++ ender = regnode(g, (paren) ? CLOSE+parno : END);
+ regtail(g, ret, ender);
+
+ /* Hook the tails of the branches to the closing node. */
+ register char c;
+ register int no;
+ register int len;
-+
++
+ /* Not necessary and gcc doesn't like it -MLS */
+ /*extern char *strncpy();*/
+
+}
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
-@@ -207,6 +207,14 @@
+@@ -205,6 +205,14 @@ destroy_conntrack(struct nf_conntrack *n
* too. */
nf_ct_remove_expectations(ct);
BUG_ON(hlist_unhashed(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode));
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
-@@ -174,7 +174,12 @@
+@@ -174,7 +174,12 @@ static int ct_seq_show(struct seq_file *
return -ENOSPC;
#endif
return 0;
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
-@@ -124,6 +124,22 @@
+@@ -124,6 +124,22 @@ struct nf_conn
u_int32_t secmark;
#endif