diff --git a/target/linux/generic/patches-2.6.39/610-netfilter_match_bypass_default_checks.patch b/target/linux/generic/patches-2.6.39/610-netfilter_match_bypass_default_checks.patch
new file mode 100644
index 0000000000000000000000000000000000000000..ac0fd151cdc16119cfd7c336357fcc2bdbfec45b
--- /dev/null
+++ b/target/linux/generic/patches-2.6.39/610-netfilter_match_bypass_default_checks.patch
@@ -0,0 +1,90 @@
+--- a/include/linux/netfilter_ipv4/ip_tables.h
++++ b/include/linux/netfilter_ipv4/ip_tables.h
+@@ -93,6 +93,7 @@ struct ipt_ip {
+ #define IPT_F_FRAG		0x01	/* Set if rule is a fragment rule */
+ #define IPT_F_GOTO		0x02	/* Set if jump is a goto */
+ #define IPT_F_MASK		0x03	/* All possible flag bits mask. */
++#define IPT_F_NO_DEF_MATCH	0x80	/* Internal: no default match rules present */
+ 
+ /* Values for "inv" field in struct ipt_ip. */
+ #define IPT_INV_VIA_IN		0x01	/* Invert the sense of IN IFACE. */
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -90,6 +90,9 @@ ip_packet_match(const struct iphdr *ip,
+ 
+ #define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg)))
+ 
++	if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
++		return true;
++
+ 	if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
+ 		  IPT_INV_SRCIP) ||
+ 	    FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
+@@ -143,6 +146,26 @@ ip_packet_match(const struct iphdr *ip,
+ 	return true;
+ }
+ 
++static void
++ip_checkdefault(struct ipt_ip *ip)
++{
++	static const char iface_mask[IFNAMSIZ] = {};
++
++	if (ip->invflags || ip->flags & IPT_F_FRAG)
++		return;
++
++	if (memcmp(ip->iniface_mask, iface_mask, IFNAMSIZ) != 0)
++		return;
++
++	if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0)
++		return;
++
++	if (ip->proto)
++		return;
++
++	ip->flags |= IPT_F_NO_DEF_MATCH;
++}
++
+ static bool
+ ip_checkentry(const struct ipt_ip *ip)
+ {
+@@ -566,7 +589,7 @@ static void cleanup_match(struct xt_entr
+ }
+ 
+ static int
+-check_entry(const struct ipt_entry *e, const char *name)
++check_entry(struct ipt_entry *e, const char *name)
+ {
+ 	const struct xt_entry_target *t;
+ 
+@@ -575,6 +598,8 @@ check_entry(const struct ipt_entry *e, c
+ 		return -EINVAL;
+ 	}
+ 
++	ip_checkdefault(&e->ip);
++
+ 	if (e->target_offset + sizeof(struct xt_entry_target) >
+ 	    e->next_offset)
+ 		return -EINVAL;
+@@ -936,6 +961,7 @@ copy_entries_to_user(unsigned int total_
+ 	const struct xt_table_info *private = table->private;
+ 	int ret = 0;
+ 	const void *loc_cpu_entry;
++	u8 flags;
+ 
+ 	counters = alloc_counters(table);
+ 	if (IS_ERR(counters))
+@@ -967,6 +993,14 @@ copy_entries_to_user(unsigned int total_
+ 			goto free_counters;
+ 		}
+ 
++		flags = e->ip.flags & IPT_F_MASK;
++		if (copy_to_user(userptr + off
++				 + offsetof(struct ipt_entry, ip.flags),
++				 &flags, sizeof(flags)) != 0) {
++			ret = -EFAULT;
++			goto free_counters;
++		}
++
+ 		for (i = sizeof(struct ipt_entry);
+ 		     i < e->target_offset;
+ 		     i += m->u.match_size) {
diff --git a/target/linux/generic/patches-2.6.39/611-netfilter_match_bypass_default_table.patch b/target/linux/generic/patches-2.6.39/611-netfilter_match_bypass_default_table.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f2004a6b12e8e4fd345b2b42c9206491113c3b70
--- /dev/null
+++ b/target/linux/generic/patches-2.6.39/611-netfilter_match_bypass_default_table.patch
@@ -0,0 +1,78 @@
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -316,6 +316,33 @@ struct ipt_entry *ipt_next_entry(const s
+ 	return (void *)entry + entry->next_offset;
+ }
+ 
++static bool
++ipt_handle_default_rule(struct ipt_entry *e, unsigned int *verdict)
++{
++	struct xt_entry_target *t;
++	struct xt_standard_target *st;
++
++	if (e->target_offset != sizeof(struct ipt_entry))
++		return false;
++
++	if (!(e->ip.flags & IPT_F_NO_DEF_MATCH))
++		return false;
++
++	t = ipt_get_target(e);
++	if (t->u.kernel.target->target)
++		return false;
++
++	st = (struct xt_standard_target *) t;
++	if (st->verdict == XT_RETURN)
++		return false;
++
++	if (st->verdict >= 0)
++		return false;
++
++	*verdict = (unsigned)(-st->verdict) - 1;
++	return true;
++}
++
+ /* Returns one of the generic firewall policies, like NF_ACCEPT. */
+ unsigned int
+ ipt_do_table(struct sk_buff *skb,
+@@ -339,6 +366,23 @@ ipt_do_table(struct sk_buff *skb,
+ 	ip = ip_hdr(skb);
+ 	indev = in ? in->name : nulldevname;
+ 	outdev = out ? out->name : nulldevname;
++
++	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
++	xt_info_rdlock_bh();
++	private = table->private;
++	cpu        = smp_processor_id();
++	table_base = private->entries[cpu];
++	jumpstack  = (struct ipt_entry **)private->jumpstack[cpu];
++	stackptr   = per_cpu_ptr(private->stackptr, cpu);
++	origptr    = *stackptr;
++
++	e = get_entry(table_base, private->hook_entry[hook]);
++	if (ipt_handle_default_rule(e, &verdict)) {
++		ADD_COUNTER(e->counters, skb->len, 1);
++		xt_info_rdunlock_bh();
++		return verdict;
++	}
++
+ 	/* We handle fragments by dealing with the first fragment as
+ 	 * if it was a normal packet.  All other fragments are treated
+ 	 * normally, except that they will NEVER match rules that ask
+@@ -353,17 +397,6 @@ ipt_do_table(struct sk_buff *skb,
+ 	acpar.family  = NFPROTO_IPV4;
+ 	acpar.hooknum = hook;
+ 
+-	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
+-	xt_info_rdlock_bh();
+-	private = table->private;
+-	cpu        = smp_processor_id();
+-	table_base = private->entries[cpu];
+-	jumpstack  = (struct ipt_entry **)private->jumpstack[cpu];
+-	stackptr   = per_cpu_ptr(private->stackptr, cpu);
+-	origptr    = *stackptr;
+-
+-	e = get_entry(table_base, private->hook_entry[hook]);
+-
+ 	pr_debug("Entering %s(hook %u); sp at %u (UF %p)\n",
+ 		 table->name, hook, origptr,
+ 		 get_entry(table_base, private->underflow[hook]));
diff --git a/target/linux/generic/patches-2.6.39/612-netfilter_match_reduce_memory_access.patch b/target/linux/generic/patches-2.6.39/612-netfilter_match_reduce_memory_access.patch
new file mode 100644
index 0000000000000000000000000000000000000000..a36a1728d187102c0c67f8e9664968b3c5d3bf7e
--- /dev/null
+++ b/target/linux/generic/patches-2.6.39/612-netfilter_match_reduce_memory_access.patch
@@ -0,0 +1,16 @@
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -93,9 +93,11 @@ ip_packet_match(const struct iphdr *ip,
+ 	if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
+ 		return true;
+ 
+-	if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
++	if (FWINV(ipinfo->smsk.s_addr &&
++		  (ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
+ 		  IPT_INV_SRCIP) ||
+-	    FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
++	    FWINV(ipinfo->smsk.s_addr &&
++		  (ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
+ 		  IPT_INV_DSTIP)) {
+ 		dprintf("Source or dest mismatch.\n");
+ 
diff --git a/target/linux/generic/patches-2.6.39/613-netfilter_optional_tcp_window_check.patch b/target/linux/generic/patches-2.6.39/613-netfilter_optional_tcp_window_check.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1c259d4f0c5b5c1c6d0da2a53ae31677b0047183
--- /dev/null
+++ b/target/linux/generic/patches-2.6.39/613-netfilter_optional_tcp_window_check.patch
@@ -0,0 +1,36 @@
+--- a/net/netfilter/nf_conntrack_proto_tcp.c
++++ b/net/netfilter/nf_conntrack_proto_tcp.c
+@@ -29,6 +29,9 @@
+ #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
+ #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
+ 
++/* Do not check the TCP window for incoming packets  */
++static int nf_ct_tcp_no_window_check __read_mostly = 1;
++
+ /* "Be conservative in what you do,
+     be liberal in what you accept from others."
+     If it's non-zero, we mark only out of window RST segments as INVALID. */
+@@ -524,6 +527,9 @@ static bool tcp_in_window(const struct n
+ 	s16 receiver_offset;
+ 	bool res;
+ 
++	if (nf_ct_tcp_no_window_check)
++		return true;
++
+ 	/*
+ 	 * Get the required data from the packet.
+ 	 */
+@@ -1321,6 +1327,13 @@ static struct ctl_table tcp_sysctl_table
+ 		.proc_handler	= proc_dointvec,
+ 	},
+ 	{
++		.procname       = "nf_conntrack_tcp_no_window_check",
++		.data           = &nf_ct_tcp_no_window_check,
++		.maxlen         = sizeof(unsigned int),
++		.mode           = 0644,
++		.proc_handler   = proc_dointvec,
++	},
++	{
+ 		.procname       = "nf_conntrack_tcp_be_liberal",
+ 		.data           = &nf_ct_tcp_be_liberal,
+ 		.maxlen         = sizeof(unsigned int),
diff --git a/target/linux/generic/patches-3.0/610-netfilter_match_bypass_default_checks.patch b/target/linux/generic/patches-3.0/610-netfilter_match_bypass_default_checks.patch
new file mode 100644
index 0000000000000000000000000000000000000000..b8ba5f7dc6ef7d1d1abe40b1aaad83764a03499d
--- /dev/null
+++ b/target/linux/generic/patches-3.0/610-netfilter_match_bypass_default_checks.patch
@@ -0,0 +1,90 @@
+--- a/include/linux/netfilter_ipv4/ip_tables.h
++++ b/include/linux/netfilter_ipv4/ip_tables.h
+@@ -93,6 +93,7 @@ struct ipt_ip {
+ #define IPT_F_FRAG		0x01	/* Set if rule is a fragment rule */
+ #define IPT_F_GOTO		0x02	/* Set if jump is a goto */
+ #define IPT_F_MASK		0x03	/* All possible flag bits mask. */
++#define IPT_F_NO_DEF_MATCH	0x80	/* Internal: no default match rules present */
+ 
+ /* Values for "inv" field in struct ipt_ip. */
+ #define IPT_INV_VIA_IN		0x01	/* Invert the sense of IN IFACE. */
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -81,6 +81,9 @@ ip_packet_match(const struct iphdr *ip,
+ 
+ #define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg)))
+ 
++	if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
++		return true;
++
+ 	if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
+ 		  IPT_INV_SRCIP) ||
+ 	    FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
+@@ -134,6 +137,26 @@ ip_packet_match(const struct iphdr *ip,
+ 	return true;
+ }
+ 
++static void
++ip_checkdefault(struct ipt_ip *ip)
++{
++	static const char iface_mask[IFNAMSIZ] = {};
++
++	if (ip->invflags || ip->flags & IPT_F_FRAG)
++		return;
++
++	if (memcmp(ip->iniface_mask, iface_mask, IFNAMSIZ) != 0)
++		return;
++
++	if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0)
++		return;
++
++	if (ip->proto)
++		return;
++
++	ip->flags |= IPT_F_NO_DEF_MATCH;
++}
++
+ static bool
+ ip_checkentry(const struct ipt_ip *ip)
+ {
+@@ -561,7 +584,7 @@ static void cleanup_match(struct xt_entr
+ }
+ 
+ static int
+-check_entry(const struct ipt_entry *e, const char *name)
++check_entry(struct ipt_entry *e, const char *name)
+ {
+ 	const struct xt_entry_target *t;
+ 
+@@ -570,6 +593,8 @@ check_entry(const struct ipt_entry *e, c
+ 		return -EINVAL;
+ 	}
+ 
++	ip_checkdefault(&e->ip);
++
+ 	if (e->target_offset + sizeof(struct xt_entry_target) >
+ 	    e->next_offset)
+ 		return -EINVAL;
+@@ -931,6 +956,7 @@ copy_entries_to_user(unsigned int total_
+ 	const struct xt_table_info *private = table->private;
+ 	int ret = 0;
+ 	const void *loc_cpu_entry;
++	u8 flags;
+ 
+ 	counters = alloc_counters(table);
+ 	if (IS_ERR(counters))
+@@ -962,6 +988,14 @@ copy_entries_to_user(unsigned int total_
+ 			goto free_counters;
+ 		}
+ 
++		flags = e->ip.flags & IPT_F_MASK;
++		if (copy_to_user(userptr + off
++				 + offsetof(struct ipt_entry, ip.flags),
++				 &flags, sizeof(flags)) != 0) {
++			ret = -EFAULT;
++			goto free_counters;
++		}
++
+ 		for (i = sizeof(struct ipt_entry);
+ 		     i < e->target_offset;
+ 		     i += m->u.match_size) {
diff --git a/target/linux/generic/patches-3.0/611-netfilter_match_bypass_default_table.patch b/target/linux/generic/patches-3.0/611-netfilter_match_bypass_default_table.patch
new file mode 100644
index 0000000000000000000000000000000000000000..113f1401232ff02ae5f386c8a0193b2abc80797a
--- /dev/null
+++ b/target/linux/generic/patches-3.0/611-netfilter_match_bypass_default_table.patch
@@ -0,0 +1,81 @@
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -307,6 +307,33 @@ struct ipt_entry *ipt_next_entry(const s
+ 	return (void *)entry + entry->next_offset;
+ }
+ 
++static bool
++ipt_handle_default_rule(struct ipt_entry *e, unsigned int *verdict)
++{
++	struct xt_entry_target *t;
++	struct xt_standard_target *st;
++
++	if (e->target_offset != sizeof(struct ipt_entry))
++		return false;
++
++	if (!(e->ip.flags & IPT_F_NO_DEF_MATCH))
++		return false;
++
++	t = ipt_get_target(e);
++	if (t->u.kernel.target->target)
++		return false;
++
++	st = (struct xt_standard_target *) t;
++	if (st->verdict == XT_RETURN)
++		return false;
++
++	if (st->verdict >= 0)
++		return false;
++
++	*verdict = (unsigned)(-st->verdict) - 1;
++	return true;
++}
++
+ /* Returns one of the generic firewall policies, like NF_ACCEPT. */
+ unsigned int
+ ipt_do_table(struct sk_buff *skb,
+@@ -331,6 +358,25 @@ ipt_do_table(struct sk_buff *skb,
+ 	ip = ip_hdr(skb);
+ 	indev = in ? in->name : nulldevname;
+ 	outdev = out ? out->name : nulldevname;
++
++	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
++	local_bh_disable();
++	addend = xt_write_recseq_begin();
++	private = table->private;
++	cpu        = smp_processor_id();
++	table_base = private->entries[cpu];
++	jumpstack  = (struct ipt_entry **)private->jumpstack[cpu];
++	stackptr   = per_cpu_ptr(private->stackptr, cpu);
++	origptr    = *stackptr;
++
++	e = get_entry(table_base, private->hook_entry[hook]);
++	if (ipt_handle_default_rule(e, &verdict)) {
++		ADD_COUNTER(e->counters, skb->len, 1);
++		xt_write_recseq_end(addend);
++		local_bh_enable();
++		return verdict;
++	}
++
+ 	/* We handle fragments by dealing with the first fragment as
+ 	 * if it was a normal packet.  All other fragments are treated
+ 	 * normally, except that they will NEVER match rules that ask
+@@ -345,18 +391,6 @@ ipt_do_table(struct sk_buff *skb,
+ 	acpar.family  = NFPROTO_IPV4;
+ 	acpar.hooknum = hook;
+ 
+-	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
+-	local_bh_disable();
+-	addend = xt_write_recseq_begin();
+-	private = table->private;
+-	cpu        = smp_processor_id();
+-	table_base = private->entries[cpu];
+-	jumpstack  = (struct ipt_entry **)private->jumpstack[cpu];
+-	stackptr   = per_cpu_ptr(private->stackptr, cpu);
+-	origptr    = *stackptr;
+-
+-	e = get_entry(table_base, private->hook_entry[hook]);
+-
+ 	pr_debug("Entering %s(hook %u); sp at %u (UF %p)\n",
+ 		 table->name, hook, origptr,
+ 		 get_entry(table_base, private->underflow[hook]));
diff --git a/target/linux/generic/patches-3.0/612-netfilter_match_reduce_memory_access.patch b/target/linux/generic/patches-3.0/612-netfilter_match_reduce_memory_access.patch
new file mode 100644
index 0000000000000000000000000000000000000000..817b37efd15b55934e25cf111ae5b375324dbf87
--- /dev/null
+++ b/target/linux/generic/patches-3.0/612-netfilter_match_reduce_memory_access.patch
@@ -0,0 +1,16 @@
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -84,9 +84,11 @@ ip_packet_match(const struct iphdr *ip,
+ 	if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
+ 		return true;
+ 
+-	if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
++	if (FWINV(ipinfo->smsk.s_addr &&
++		  (ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
+ 		  IPT_INV_SRCIP) ||
+-	    FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
++	    FWINV(ipinfo->smsk.s_addr &&
++		  (ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
+ 		  IPT_INV_DSTIP)) {
+ 		dprintf("Source or dest mismatch.\n");
+ 
diff --git a/target/linux/generic/patches-3.0/613-netfilter_optional_tcp_window_check.patch b/target/linux/generic/patches-3.0/613-netfilter_optional_tcp_window_check.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1c259d4f0c5b5c1c6d0da2a53ae31677b0047183
--- /dev/null
+++ b/target/linux/generic/patches-3.0/613-netfilter_optional_tcp_window_check.patch
@@ -0,0 +1,36 @@
+--- a/net/netfilter/nf_conntrack_proto_tcp.c
++++ b/net/netfilter/nf_conntrack_proto_tcp.c
+@@ -29,6 +29,9 @@
+ #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
+ #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
+ 
++/* Do not check the TCP window for incoming packets  */
++static int nf_ct_tcp_no_window_check __read_mostly = 1;
++
+ /* "Be conservative in what you do,
+     be liberal in what you accept from others."
+     If it's non-zero, we mark only out of window RST segments as INVALID. */
+@@ -524,6 +527,9 @@ static bool tcp_in_window(const struct n
+ 	s16 receiver_offset;
+ 	bool res;
+ 
++	if (nf_ct_tcp_no_window_check)
++		return true;
++
+ 	/*
+ 	 * Get the required data from the packet.
+ 	 */
+@@ -1321,6 +1327,13 @@ static struct ctl_table tcp_sysctl_table
+ 		.proc_handler	= proc_dointvec,
+ 	},
+ 	{
++		.procname       = "nf_conntrack_tcp_no_window_check",
++		.data           = &nf_ct_tcp_no_window_check,
++		.maxlen         = sizeof(unsigned int),
++		.mode           = 0644,
++		.proc_handler   = proc_dointvec,
++	},
++	{
+ 		.procname       = "nf_conntrack_tcp_be_liberal",
+ 		.data           = &nf_ct_tcp_be_liberal,
+ 		.maxlen         = sizeof(unsigned int),