From: Michael Tremer Date: Sun, 30 Mar 2014 21:26:29 +0000 (+0200) Subject: kernel: Update layer7 patch. X-Git-Url: http://git.ipfire.org/?p=people%2Fteissler%2Fipfire-2.x.git;a=commitdiff_plain;h=af8c09ff3859a11cd04dc0ae14997fd004e85424 kernel: Update layer7 patch. Brings back the /proc interface and is supposed to fix a memory leak. --- diff --git a/lfs/linux b/lfs/linux index bfc1580e7..e0be9e32c 100644 --- a/lfs/linux +++ b/lfs/linux @@ -118,7 +118,7 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.10-ipp2p-0.8.2-ipfire.patch # Layer7-patch - cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/netfilter_layer7_2.22_kernel3.10-no_proc_interface.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.10-layer7-filter.patch # Grsecurity-patches ifneq "$(KCFG)" "-headers" diff --git a/src/patches/netfilter_layer7_2.22_kernel3.10-no_proc_interface.patch b/src/patches/linux-3.10-layer7-filter.patch similarity index 86% rename from src/patches/netfilter_layer7_2.22_kernel3.10-no_proc_interface.patch rename to src/patches/linux-3.10-layer7-filter.patch index 5ffdd4936..4cf2a1ceb 100644 --- a/src/patches/netfilter_layer7_2.22_kernel3.10-no_proc_interface.patch +++ b/src/patches/linux-3.10-layer7-filter.patch @@ -1,7 +1,11 @@ -diff -Naur linux-3.10.5.org/include/linux/netfilter/xt_layer7.h linux-3.10.5/include/linux/netfilter/xt_layer7.h ---- linux-3.10.5.org/include/linux/netfilter/xt_layer7.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.10.5/include/linux/netfilter/xt_layer7.h 2013-08-07 06:16:14.260806739 +0200 -@@ -0,0 +1,13 @@ +http://git.ipfire.org/?p=people/ms/linux.git;a=shortlog;h=refs/heads/linux-3.10.y-layer7 + +diff --git a/include/linux/netfilter/xt_layer7.h b/include/linux/netfilter/xt_layer7.h +new file mode 100644 +index 0000000..c38d3c4 +--- /dev/null ++++ b/include/linux/netfilter/xt_layer7.h +@@ -0,0 +1,14 @@ +#ifndef _XT_LAYER7_H +#define _XT_LAYER7_H + @@ -12,18 +16,20 @@ diff -Naur linux-3.10.5.org/include/linux/netfilter/xt_layer7.h linux-3.10.5/inc + char protocol[MAX_PROTOCOL_LEN]; + char pattern[MAX_PATTERN_LEN]; + u_int8_t invert; ++ u_int8_t pkt; +}; + +#endif /* _XT_LAYER7_H */ -diff -Naur linux-3.10.5.org/include/net/netfilter/nf_conntrack.h linux-3.10.5/include/net/netfilter/nf_conntrack.h ---- linux-3.10.5.org/include/net/netfilter/nf_conntrack.h 2013-08-04 10:51:49.000000000 +0200 -+++ linux-3.10.5/include/net/netfilter/nf_conntrack.h 2013-08-07 06:16:14.280806062 +0200 -@@ -105,6 +105,22 @@ +diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h +index 644d9c2..b226a8f 100644 +--- a/include/net/netfilter/nf_conntrack.h ++++ b/include/net/netfilter/nf_conntrack.h +@@ -105,6 +105,22 @@ struct nf_conn { struct net *ct_net; #endif +#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || \ -+ defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE) ++ defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE) + struct { + /* + * e.g. "http". NULL before decision. "unknown" after decision @@ -41,17 +47,31 @@ diff -Naur linux-3.10.5.org/include/net/netfilter/nf_conntrack.h linux-3.10.5/in /* Storage reserved for other modules, must be the last member */ union nf_conntrack_proto proto; }; -diff -Naur linux-3.10.5.org/net/netfilter/Kconfig linux-3.10.5/net/netfilter/Kconfig ---- linux-3.10.5.org/net/netfilter/Kconfig 2013-08-04 10:51:49.000000000 +0200 -+++ linux-3.10.5/net/netfilter/Kconfig 2013-08-07 06:16:14.310805048 +0200 -@@ -1205,6 +1205,26 @@ +diff --git a/include/uapi/linux/netfilter/Kbuild b/include/uapi/linux/netfilter/Kbuild +index 4111577..a95e6b5 100644 +--- a/include/uapi/linux/netfilter/Kbuild ++++ b/include/uapi/linux/netfilter/Kbuild +@@ -53,6 +53,7 @@ header-y += xt_hashlimit.h + header-y += xt_helper.h + header-y += xt_iprange.h + header-y += xt_ipvs.h ++header-y += xt_layer7.h + header-y += xt_length.h + header-y += xt_limit.h + header-y += xt_mac.h +diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig +index 56d22ca..7827ba4 100644 +--- a/net/netfilter/Kconfig ++++ b/net/netfilter/Kconfig +@@ -1011,6 +1011,26 @@ config NETFILTER_XT_MATCH_IPVS - To compile it as a module, choose M here. If unsure, say N. + If unsure, say N. +config NETFILTER_XT_MATCH_LAYER7 + tristate '"layer7" match support' + depends on NETFILTER_XTABLES -+ depends on IP_NF_CONNTRACK || NF_CONNTRACK ++ depends on NETFILTER_ADVANCED ++ depends on NF_CONNTRACK + help + Say Y if you want to be able to classify connections (and their + packets) based on regular expression matching of their application @@ -62,19 +82,32 @@ diff -Naur linux-3.10.5.org/net/netfilter/Kconfig linux-3.10.5/net/netfilter/Kco + To compile it as a module, choose M here. If unsure, say N. + +config NETFILTER_XT_MATCH_LAYER7_DEBUG -+ bool 'Layer 7 debugging output' -+ depends on NETFILTER_XT_MATCH_LAYER7 -+ help -+ Say Y to get lots of debugging output. ++ bool 'Layer 7 debugging output' ++ depends on NETFILTER_XT_MATCH_LAYER7 ++ help ++ Say Y to get lots of debugging output. + + config NETFILTER_XT_MATCH_LENGTH + tristate '"length" match support' + depends on NETFILTER_ADVANCED +@@ -1205,6 +1225,12 @@ config NETFILTER_XT_MATCH_STATE + + To compile it as a module, choose M here. If unsure, say N. + ++config NETFILTER_XT_MATCH_LAYER7_DEBUG ++ bool 'Layer 7 debugging output' ++ depends on NETFILTER_XT_MATCH_LAYER7 ++ help ++ Say Y to get lots of debugging output. + config NETFILTER_XT_MATCH_STATISTIC tristate '"statistic" match support' depends on NETFILTER_ADVANCED -diff -Naur linux-3.10.5.org/net/netfilter/Makefile linux-3.10.5/net/netfilter/Makefile ---- linux-3.10.5.org/net/netfilter/Makefile 2013-08-04 10:51:49.000000000 +0200 -+++ linux-3.10.5/net/netfilter/Makefile 2013-08-07 06:16:14.320804710 +0200 -@@ -134,6 +134,7 @@ +diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile +index a1abf87..acec24e 100644 +--- a/net/netfilter/Makefile ++++ b/net/netfilter/Makefile +@@ -134,6 +134,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT) += xt_recent.o obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o @@ -82,34 +115,29 @@ diff -Naur linux-3.10.5.org/net/netfilter/Makefile linux-3.10.5/net/netfilter/Ma obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o -diff -Naur linux-3.10.5.org/net/netfilter/nf_conntrack_core.c linux-3.10.5/net/netfilter/nf_conntrack_core.c ---- linux-3.10.5.org/net/netfilter/nf_conntrack_core.c 2013-08-04 10:51:49.000000000 +0200 -+++ linux-3.10.5/net/netfilter/nf_conntrack_core.c 2013-08-07 06:20:34.941991510 +0200 -@@ -1,3 +1,6 @@ -+ -+ -+ - /* Connection state tracking for netfilter. This is separated from, - but required by, the NAT layer; it can also be used by an iptables - extension. */ -@@ -224,6 +227,13 @@ +diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c +index 0283bae..cae3790 100644 +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -224,6 +224,13 @@ destroy_conntrack(struct nf_conntrack *nfct) * too. */ nf_ct_remove_expectations(ct); -+ #if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE) ++#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE) + if(ct->layer7.app_proto) + kfree(ct->layer7.app_proto); + if(ct->layer7.app_data) -+ kfree(ct->layer7.app_data); -+ #endif ++ kfree(ct->layer7.app_data); ++#endif + /* We overload first tuple to link into unconfirmed or dying list.*/ BUG_ON(hlist_nulls_unhashed(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode)); hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode); -diff -Naur linux-3.10.5.org/net/netfilter/nf_conntrack_standalone.c linux-3.10.5/net/netfilter/nf_conntrack_standalone.c ---- linux-3.10.5.org/net/netfilter/nf_conntrack_standalone.c 2013-08-04 10:51:49.000000000 +0200 -+++ linux-3.10.5/net/netfilter/nf_conntrack_standalone.c 2013-08-07 06:16:14.380802681 +0200 -@@ -240,6 +240,12 @@ +diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c +index bd700b4..5d045ca 100644 +--- a/net/netfilter/nf_conntrack_standalone.c ++++ b/net/netfilter/nf_conntrack_standalone.c +@@ -240,6 +240,12 @@ static int ct_seq_show(struct seq_file *s, void *v) if (ct_show_delta_time(s, ct)) goto release; @@ -122,9 +150,11 @@ diff -Naur linux-3.10.5.org/net/netfilter/nf_conntrack_standalone.c linux-3.10.5 if (seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use))) goto release; -diff -Naur linux-3.10.5.org/net/netfilter/regexp/regexp.c linux-3.10.5/net/netfilter/regexp/regexp.c ---- linux-3.10.5.org/net/netfilter/regexp/regexp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.10.5/net/netfilter/regexp/regexp.c 2013-08-07 06:16:14.410801666 +0200 +diff --git a/net/netfilter/regexp/regexp.c b/net/netfilter/regexp/regexp.c +new file mode 100644 +index 0000000..9006988 +--- /dev/null ++++ b/net/netfilter/regexp/regexp.c @@ -0,0 +1,1197 @@ +/* + * regcomp and regexec -- regsub and regerror are elsewhere @@ -1323,9 +1353,11 @@ diff -Naur linux-3.10.5.org/net/netfilter/regexp/regexp.c linux-3.10.5/net/netfi +#endif + + -diff -Naur linux-3.10.5.org/net/netfilter/regexp/regexp.h linux-3.10.5/net/netfilter/regexp/regexp.h ---- linux-3.10.5.org/net/netfilter/regexp/regexp.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.10.5/net/netfilter/regexp/regexp.h 2013-08-07 06:16:14.430800990 +0200 +diff --git a/net/netfilter/regexp/regexp.h b/net/netfilter/regexp/regexp.h +new file mode 100644 +index 0000000..a72eba7 +--- /dev/null ++++ b/net/netfilter/regexp/regexp.h @@ -0,0 +1,41 @@ +/* + * Definitions etc. for regexp(3) routines. @@ -1368,18 +1400,22 @@ diff -Naur linux-3.10.5.org/net/netfilter/regexp/regexp.h linux-3.10.5/net/netfi +void regerror(char *s); + +#endif -diff -Naur linux-3.10.5.org/net/netfilter/regexp/regmagic.h linux-3.10.5/net/netfilter/regexp/regmagic.h ---- linux-3.10.5.org/net/netfilter/regexp/regmagic.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.10.5/net/netfilter/regexp/regmagic.h 2013-08-07 06:16:14.450800314 +0200 +diff --git a/net/netfilter/regexp/regmagic.h b/net/netfilter/regexp/regmagic.h +new file mode 100644 +index 0000000..5acf447 +--- /dev/null ++++ b/net/netfilter/regexp/regmagic.h @@ -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 -Naur linux-3.10.5.org/net/netfilter/regexp/regsub.c linux-3.10.5/net/netfilter/regexp/regsub.c ---- linux-3.10.5.org/net/netfilter/regexp/regsub.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.10.5/net/netfilter/regexp/regsub.c 2013-08-07 06:16:14.450800314 +0200 +diff --git a/net/netfilter/regexp/regsub.c b/net/netfilter/regexp/regsub.c +new file mode 100644 +index 0000000..339631f +--- /dev/null ++++ b/net/netfilter/regexp/regsub.c @@ -0,0 +1,95 @@ +/* + * regsub @@ -1476,10 +1512,12 @@ diff -Naur linux-3.10.5.org/net/netfilter/regexp/regsub.c linux-3.10.5/net/netfi + } + *dst++ = '\0'; +} -diff -Naur linux-3.10.5.org/net/netfilter/xt_layer7.c linux-3.10.5/net/netfilter/xt_layer7.c ---- linux-3.10.5.org/net/netfilter/xt_layer7.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.10.5/net/netfilter/xt_layer7.c 2013-08-07 06:16:14.490798961 +0200 -@@ -0,0 +1,684 @@ +diff --git a/net/netfilter/xt_layer7.c b/net/netfilter/xt_layer7.c +new file mode 100644 +index 0000000..51bb747 +--- /dev/null ++++ b/net/netfilter/xt_layer7.c +@@ -0,0 +1,625 @@ +/* + Kernel module to match application layer (OSI layer 7) data in connections. + @@ -1503,14 +1541,13 @@ diff -Naur linux-3.10.5.org/net/netfilter/xt_layer7.c linux-3.10.5/net/netfilter +#include +#include +#include ++#include +#include +#include +#include +#include -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) +#include +#include -+#endif +#include +#include +#include @@ -1522,7 +1559,7 @@ diff -Naur linux-3.10.5.org/net/netfilter/xt_layer7.c linux-3.10.5/net/netfilter +MODULE_AUTHOR("Matthew Strait , Ethan Sommer "); +MODULE_DESCRIPTION("iptables application layer match module"); +MODULE_ALIAS("ipt_layer7"); -+MODULE_VERSION("2.22ipfire"); ++MODULE_VERSION("2.21"); + +static int maxdatalen = 2048; // this is the default +module_param(maxdatalen, int, 0444); @@ -1547,18 +1584,13 @@ diff -Naur linux-3.10.5.org/net/netfilter/xt_layer7.c linux-3.10.5/net/netfilter + +static int total_acct_packets(struct nf_conn *ct) +{ -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26) -+ BUG_ON(ct == NULL); -+ return (ct->counters[IP_CT_DIR_ORIGINAL].packets + ct->counters[IP_CT_DIR_REPLY].packets); -+#else + struct nf_conn_counter *acct; + + BUG_ON(ct == NULL); + acct = nf_conn_acct_find(ct); + if (!acct) + return 0; -+ return ( atomic64_read(&acct[IP_CT_DIR_ORIGINAL].packets) + atomic64_read(&acct[IP_CT_DIR_REPLY].packets) ); -+#endif ++ return (atomic64_read(&acct[IP_CT_DIR_ORIGINAL].packets) + atomic64_read(&acct[IP_CT_DIR_REPLY].packets)); +} + +#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG @@ -1678,7 +1710,7 @@ diff -Naur linux-3.10.5.org/net/netfilter/xt_layer7.c linux-3.10.5/net/netfilter + + /* copy the string and compile the regex */ + len = strlen(regex_string); -+ DPRINTK("layer7: about to compile this: \"%s\"\n", regex_string); ++ DPRINTK("About to compile this: \"%s\"\n", regex_string); + node->pattern = regcomp((char *)regex_string, &len); + if ( !node->pattern ) { + if (net_ratelimit()) @@ -1796,33 +1828,35 @@ diff -Naur linux-3.10.5.org/net/netfilter/xt_layer7.c linux-3.10.5/net/netfilter +} + +/* add the new app data to the conntrack. Return number of bytes added. */ -+static int add_data(struct nf_conn * 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') { + /* the kernel version of tolower mungs 'upper ascii' */ -+ master_conntrack->layer7.app_data[length+oldlength] = ++ target[length+offset] = + 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 nf_conn * master_conntrack, ++ char * app_data, int appdatalen) ++{ ++ int length; + -+ master_conntrack->layer7.app_data[length+oldlength] = '\0'; -+ master_conntrack->layer7.app_data_len = length + oldlength; ++ 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; +} @@ -1843,86 +1877,47 @@ diff -Naur linux-3.10.5.org/net/netfilter/xt_layer7.c linux-3.10.5/net/netfilter + } +} + -+/* write out num_packets to userland. */ -+static int layer7_read_proc(char* page, char ** start, off_t off, int count, -+ int* eof, void * data) -+{ -+ if(num_packets > 99 && net_ratelimit()) -+ printk(KERN_ERR "layer7: NOT REACHED. num_packets too big\n"); ++static int layer7_numpackets_proc_show(struct seq_file *s, void *p) { ++ seq_printf(s, "%d\n", num_packets); + -+ page[0] = num_packets/10 + '0'; -+ page[1] = num_packets%10 + '0'; -+ page[2] = '\n'; -+ page[3] = '\0'; -+ -+ *eof=1; ++ return 0; ++} + -+ return 3; ++static int layer7_numpackets_proc_open(struct inode *inode, struct file *file) { ++ return single_open(file, layer7_numpackets_proc_show, NULL); +} + +/* Read in num_packets from userland */ -+static int layer7_write_proc(struct file* file, const char* buffer, -+ unsigned long count, void *data) -+{ -+ char * foo = kmalloc(count, GFP_ATOMIC); ++static ssize_t layer7_numpackets_write_proc(struct file* file, const char __user *buffer, ++ size_t count, loff_t *data) { ++ char value[1024]; ++ int new_num_packets; + -+ if(!foo){ -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory, bailing. " -+ "num_packets unchanged.\n"); -+ return count; -+ } -+ -+ if(copy_from_user(foo, buffer, count)) { ++ if (copy_from_user(&value, buffer, sizeof(value))) + return -EFAULT; -+ } -+ + -+ num_packets = my_atoi(foo); -+ kfree (foo); ++ new_num_packets = my_atoi(value); + -+ /* This has an arbitrary limit to make the math easier. I'm lazy. -+ But anyway, 99 is a LOT! If you want more, you're doing it wrong! */ -+ if(num_packets > 99) { -+ printk(KERN_WARNING "layer7: num_packets can't be > 99.\n"); -+ num_packets = 99; -+ } else if(num_packets < 1) { -+ printk(KERN_WARNING "layer7: num_packets can't be < 1.\n"); -+ num_packets = 1; ++ if ((new_num_packets < 1) || (new_num_packets > 99)) { ++ printk(KERN_WARNING "layer7: numpackets must be between 1 and 99\n"); ++ return -EFAULT; + } + ++ num_packets = new_num_packets; ++ + return count; +} + -+static bool -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) -+match(const struct sk_buff *skbin, struct xt_action_param *par) -+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) -+match(const struct sk_buff *skbin, const struct xt_match_param *par) -+#else -+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, -+ bool *hotdrop) -+#endif ++static bool match(const struct sk_buff *skbin, struct xt_action_param *par) +{ + /* sidestep const without getting a compiler warning... */ + struct sk_buff * skb = (struct sk_buff *)skbin; + -+ const struct xt_layer7_info * info = -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) -+ par->matchinfo; -+ #else -+ matchinfo; -+ #endif ++ const struct xt_layer7_info * info = par->matchinfo; + + enum ip_conntrack_info master_ctinfo, ctinfo; + struct nf_conn *master_conntrack, *conntrack; -+ unsigned char * app_data; ++ unsigned char *app_data, *tmp_data; + unsigned int pattern_result, appdatalen; + regexp * comppattern; + @@ -1950,8 +1945,8 @@ diff -Naur linux-3.10.5.org/net/netfilter/xt_layer7.c linux-3.10.5/net/netfilter + master_conntrack = master_ct(master_conntrack); + + /* if we've classified it or seen too many packets */ -+ if(total_acct_packets(master_conntrack) > num_packets || -+ master_conntrack->layer7.app_proto) { ++ if(!info->pkt && (total_acct_packets(master_conntrack) > num_packets || ++ master_conntrack->layer7.app_proto)) { + + pattern_result = match_no_append(conntrack, master_conntrack, + ctinfo, master_ctinfo, info); @@ -1984,6 +1979,25 @@ diff -Naur linux-3.10.5.org/net/netfilter/xt_layer7.c linux-3.10.5/net/netfilter + /* the return value gets checked later, when we're ready to use it */ + comppattern = compile_and_cache(info->pattern, info->protocol); + ++ 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; ++ spin_unlock_bh(&l7_lock); ++ ++ return (pattern_result ^ info->invert); ++ } ++ + /* On the first packet of a connection, allocate space for app data */ + if(total_acct_packets(master_conntrack) == 1 && !skb->cb[0] && + !master_conntrack->layer7.app_data){ @@ -2060,49 +2074,21 @@ diff -Naur linux-3.10.5.org/net/netfilter/xt_layer7.c linux-3.10.5/net/netfilter +} + +// load nf_conntrack_ipv4 -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) -+static int -+#else -+static bool -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) -+check(const struct xt_mtchk_param *par) ++static int check(const struct xt_mtchk_param *par) +{ + if (nf_ct_l3proto_try_module_get(par->match->family) < 0) { + printk(KERN_WARNING "can't load conntrack support for " + "proto=%d\n", par->match->family); -+#else -+check(const char *tablename, const void *inf, -+ const struct xt_match *match, void *matchinfo, -+ unsigned int hook_mask) -+{ -+ if (nf_ct_l3proto_try_module_get(match->family) < 0) { -+ printk(KERN_WARNING "can't load conntrack support for " -+ "proto=%d\n", match->family); -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) + return -EINVAL; + } + return 0; -+#else -+ return 0; -+ } -+ return 1; -+#endif +} + + -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) -+ static void destroy(const struct xt_mtdtor_param *par) -+ { -+ nf_ct_l3proto_module_put(par->match->family); -+ } -+#else -+ static void destroy(const struct xt_match *match, void *matchinfo) -+ { -+ nf_ct_l3proto_module_put(match->family); -+ } -+#endif ++static void destroy(const struct xt_mtdtor_param *par) ++{ ++ nf_ct_l3proto_module_put(par->match->family); ++} + +static struct xt_match xt_layer7_match[] __read_mostly = { +{ @@ -2116,30 +2102,23 @@ diff -Naur linux-3.10.5.org/net/netfilter/xt_layer7.c linux-3.10.5/net/netfilter +} +}; + -+static void layer7_cleanup_proc(void) -+{ -+// remove_proc_entry("layer7_numpackets", init_net.proc_net); -+} -+ -+/* register the proc file */ -+static void layer7_init_proc(void) -+{ -+ struct proc_dir_entry* entry; -+// entry = create_proc_entry("layer7_numpackets", 0644, init_net.proc_net); -+// entry->read_proc = layer7_read_proc; -+// entry->write_proc = layer7_write_proc; -+} ++static const struct file_operations layer7_numpackets_proc_fops = { ++ .owner = THIS_MODULE, ++ .open = layer7_numpackets_proc_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++ .write = layer7_numpackets_write_proc, ++}; + +static int __init xt_layer7_init(void) +{ + need_conntrack(); + -+ if (init_net.ct.sysctl_acct == 0) { -+ printk(KERN_WARNING "layer7: enabling nf_conntrack_acct\n"); -+ init_net.ct.sysctl_acct = 1; -+ } ++ // Register proc interface ++ proc_create_data("layer7_numpackets", 0644, ++ init_net.proc_net, &layer7_numpackets_proc_fops, NULL); + -+ layer7_init_proc(); + if(maxdatalen < 1) { + printk(KERN_WARNING "layer7: maxdatalen can't be < 1, " + "using 1\n"); @@ -2158,7 +2137,7 @@ diff -Naur linux-3.10.5.org/net/netfilter/xt_layer7.c linux-3.10.5/net/netfilter + +static void __exit xt_layer7_fini(void) +{ -+ layer7_cleanup_proc(); ++ remove_proc_entry("layer7_numpackets", init_net.proc_net); + xt_unregister_matches(xt_layer7_match, ARRAY_SIZE(xt_layer7_match)); +} +