All of lore.kernel.org
 help / color / mirror / Atom feed
* RHEL backported '--queue-bypass'
@ 2012-07-24 12:11 kay
  2012-07-25  9:21 ` kay
  0 siblings, 1 reply; 8+ messages in thread
From: kay @ 2012-07-24 12:11 UTC (permalink / raw)
  To: netfilter

[-- Attachment #1: Type: text/plain, Size: 709 bytes --]

Hello,

I've backported 'queue bypass' patch from 2.6.39 to RHEL 2.6.32 kernel
(centos6.2). Many thanks to Florian Westphal.

The origin patches I used:
https://git.netfilter.org/cgi-bin/gitweb.cgi?p=iptables.git;a=commit;h=6924b4987d88fbe383bec4da4cf331cc466c245e
https://git.netfilter.org/cgi-bin/gitweb.cgi?p=iptables.git;a=commit;h=3c461ceeed5f55599930051f6feaec014b08f730
http://bugzilla.netfilter.org/show_bug.cgi?id=778
http://thread.gmane.org/gmane.linux.network/184302/focus=184239 (patches 72-75)

Patches attached are ready to be applied by rpmbuild spec.

It works fine for me but I would like to publish it for review. Maybe
someone needs this functionality too or will find some bugs.

Regards.

[-- Attachment #2: iptables-1.4.7-queue_bypass.patch --]
[-- Type: application/octet-stream, Size: 4772 bytes --]

diff -dur iptables-1.4.7/extensions/libxt_NFQUEUE.c iptables-1.4.7_/extensions/libxt_NFQUEUE.c
--- iptables-1.4.7/extensions/libxt_NFQUEUE.c	2010-03-01 17:11:28.000000000 +0300
+++ iptables-1.4.7_/extensions/libxt_NFQUEUE.c	2012-07-23 19:08:15.187576124 +0400
@@ -30,9 +30,17 @@
 "  --queue-balance first:last	Balance flows between queues <value> to <value>.\n");
 }
 
+static void NFQUEUE_help_v2(void)
+{
+	NFQUEUE_help_v1();
+	printf(
+"  --queue-bypass		Bypass Queueing if no queue instance exists.\n");
+}
+
 static const struct option NFQUEUE_opts[] = {
 	{ "queue-num", 1, NULL, 'F' },
 	{ "queue-balance", 1, NULL, 'B' },
+	{ "queue-bypass", 0, NULL, 'P'},
 	{ .name = NULL }
 };
 
@@ -120,6 +128,18 @@
 	return 1;
 }
 
+static int
+NFQUEUE_parse_v2(int c, char **argv, int invert, unsigned int *flags,
+                 const void *entry, struct xt_entry_target **target)
+{
+	if (c == 'P') {
+		struct xt_NFQ_info_v2 *info = (void *)(*target)->data;
+		info->bypass = 1;
+		return 1;
+	}
+	return NFQUEUE_parse_v1(c, argv, invert, flags, entry, target);
+}
+
 static void NFQUEUE_print(const void *ip,
                           const struct xt_entry_target *target, int numeric)
 {
@@ -142,6 +162,16 @@
 	}
 }
 
+static void NFQUEUE_print_v2(const void *ip,
+                             const struct xt_entry_target *target, int numeric)
+{
+	const struct xt_NFQ_info_v2 *info = (void *) target->data;
+
+	NFQUEUE_print_v1(ip, target, numeric);
+	if (info->bypass)
+		printf(" bypass");
+}
+
 static void NFQUEUE_save(const void *ip, const struct xt_entry_target *target)
 {
 	const struct xt_NFQ_info *tinfo =
@@ -163,13 +193,24 @@
 	}
 }
 
+static void NFQUEUE_save_v2(const void *ip, const struct xt_entry_target *target)
+{
+	const struct xt_NFQ_info_v2 *info = (void *) target->data;
+
+	NFQUEUE_save_v1(ip, target);
+
+	if (info->bypass)
+		printf(" --queue-bypass");
+}
+
 static void NFQUEUE_init_v1(struct xt_entry_target *t)
 {
 	struct xt_NFQ_info_v1 *tinfo = (void *)t->data;
 	tinfo->queues_total = 1;
 }
 
-static struct xtables_target nfqueue_target = {
+static struct xtables_target nfqueue_targets[] = {
+{
 	.family		= NFPROTO_UNSPEC,
 	.name		= "NFQUEUE",
 	.version	= XTABLES_VERSION,
@@ -180,9 +221,7 @@
 	.print		= NFQUEUE_print,
 	.save		= NFQUEUE_save,
 	.extra_opts	= NFQUEUE_opts
-};
-
-static struct xtables_target nfqueue_target_v1 = {
+},{
 	.family		= NFPROTO_UNSPEC,
 	.revision	= 1,
 	.name		= "NFQUEUE",
@@ -195,10 +234,23 @@
 	.print		= NFQUEUE_print_v1,
 	.save		= NFQUEUE_save_v1,
 	.extra_opts	= NFQUEUE_opts,
+},{
+	.family		= NFPROTO_UNSPEC,
+	.revision	= 2,
+	.name		= "NFQUEUE",
+	.version	= XTABLES_VERSION,
+	.size		= XT_ALIGN(sizeof(struct xt_NFQ_info_v2)),
+	.userspacesize	= XT_ALIGN(sizeof(struct xt_NFQ_info_v2)),
+	.help		= NFQUEUE_help_v2,
+	.init		= NFQUEUE_init_v1,
+	.parse		= NFQUEUE_parse_v2,
+	.print		= NFQUEUE_print_v2,
+	.save		= NFQUEUE_save_v2,
+	.extra_opts	= NFQUEUE_opts,
+}
 };
 
 void _init(void)
 {
-	xtables_register_target(&nfqueue_target);
-	xtables_register_target(&nfqueue_target_v1);
+	xtables_register_targets(nfqueue_targets, ARRAY_SIZE(nfqueue_targets));
 }
diff -dur iptables-1.4.7/extensions/libxt_NFQUEUE.man iptables-1.4.7_/extensions/libxt_NFQUEUE.man
--- iptables-1.4.7/extensions/libxt_NFQUEUE.man	2010-03-01 17:11:28.000000000 +0300
+++ iptables-1.4.7_/extensions/libxt_NFQUEUE.man	2012-07-23 19:10:05.404455242 +0400
@@ -5,7 +5,8 @@
 the
 .B
 nfnetlink_queue
-kernel support. The \fBqueue-balance\fP option was added in Linux 2.6.31.
+kernel support. The \fBqueue-balance\fP option was added in Linux 2.6.31,
+\fBqueue-bypass\fP in 2.6.39.
 .TP
 \fB\-\-queue\-num\fP \fIvalue\fP
 This specifies the QUEUE number to use. Valid queue numbers are 0 to 65535. The default value is 0.
@@ -16,3 +17,9 @@
 This is useful for multicore systems: start multiple instances of the userspace program on
 queues x, x+1, .. x+n and use "\-\-queue\-balance \fIx\fP\fB:\fP\fIx+n\fP".
 Packets belonging to the same connection are put into the same nfqueue.
+.PP
+.TP
+\fB\-\-queue\-bypass\fP
+By default, if no userspace program is listening on an NFQUEUE, then all packets that are to be queued
+are dropped.  When this option is used, the NFQUEUE rule is silently bypassed instead. The packet
+will move on to the next rule.
diff -dur iptables-1.4.7/include/linux/netfilter/xt_NFQUEUE.h iptables-1.4.7_/include/linux/netfilter/xt_NFQUEUE.h
--- iptables-1.4.7/include/linux/netfilter/xt_NFQUEUE.h	2010-03-01 17:11:28.000000000 +0300
+++ iptables-1.4.7_/include/linux/netfilter/xt_NFQUEUE.h	2012-07-23 19:08:57.574203436 +0400
@@ -20,4 +20,10 @@
 	__u16 queues_total;
 };
 
+struct xt_NFQ_info_v2 {
+	__u16 queuenum;
+	__u16 queues_total;
+	__u16 bypass;
+};
+
 #endif /* _XT_NFQ_TARGET_H */

[-- Attachment #3: kernel.spec.diff --]
[-- Type: application/octet-stream, Size: 655 bytes --]

--- kernel.spec_old	2012-04-26 21:29:49.000000000 +0400
+++ kernel.spec	2012-07-24 15:14:09.044235813 +0400
@@ -602,6 +602,7 @@
 Source83: config-x86_64-debug-rhel
 
 # empty final patch file to facilitate testing of kernel patches
+Patch999998: linux-kernel-queue_bypass.patch
 Patch999999: linux-kernel-test.patch
 
 BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
@@ -912,6 +913,7 @@
 # Dynamically generate kernel .config files from config-* files
 make -f %{SOURCE20} VERSION=%{version} configs
 
+ApplyOptionalPatch linux-kernel-queue_bypass.patch
 ApplyOptionalPatch linux-kernel-test.patch
 
 # Any further pre-build tree manipulations happen here.

[-- Attachment #4: iptables.spec.diff --]
[-- Type: application/octet-stream, Size: 627 bytes --]

--- iptables.spec_old	2012-02-03 20:51:51.000000000 +0400
+++ iptables.spec	2012-07-24 14:30:10.896450638 +0400
@@ -10,6 +10,7 @@
 Patch7: iptables-1.4.7-tproxy.patch
 Patch8: iptables-1.4.7-xt_AUDIT_v2.patch
 Patch9: iptables-1.4.7-opt_parser_v2.patch
+Patch10: iptables-1.4.7-queue_bypass.patch
 Group: System Environment/Base
 URL: http://www.netfilter.org/
 BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
@@ -60,6 +61,7 @@
 %patch7 -p1 -b .tproxy
 %patch8 -p1 -b .xt_AUDIT_v2
 %patch9 -p1 -b .opt_parser_v2
+%patch10 -p1 -b .queue_bypass
 
 %build
 CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" \

[-- Attachment #5: linux-kernel-queue_bypass.patch --]
[-- Type: application/octet-stream, Size: 12233 bytes --]

diff -dur linux-2.6.32-220.17.1.el6/include/linux/netfilter/xt_NFQUEUE.h linux-2.6.32-220.17.1.el6_patched/include/linux/netfilter/xt_NFQUEUE.h
--- linux-2.6.32-220.17.1.el6/include/linux/netfilter/xt_NFQUEUE.h	2009-12-03 06:51:21.000000000 +0300
+++ linux-2.6.32-220.17.1.el6_patched/include/linux/netfilter/xt_NFQUEUE.h	2012-07-19 16:22:17.000000000 +0400
@@ -20,4 +20,10 @@
 	__u16 queues_total;
 };
 
+struct xt_NFQ_info_v2 {
+	__u16 queuenum;
+	__u16 queues_total;
+	__u16 bypass;
+};
+
 #endif /* _XT_NFQ_TARGET_H */
diff -dur linux-2.6.32-220.17.1.el6/include/linux/netfilter.h linux-2.6.32-220.17.1.el6_patched/include/linux/netfilter.h
--- linux-2.6.32-220.17.1.el6/include/linux/netfilter.h	2012-04-26 20:51:06.000000000 +0400
+++ linux-2.6.32-220.17.1.el6_patched/include/linux/netfilter.h	2012-07-19 16:21:24.000000000 +0400
@@ -24,16 +24,20 @@
 #define NF_MAX_VERDICT NF_STOP
 
 /* we overload the higher bits for encoding auxiliary data such as the queue
- * number. Not nice, but better than additional function arguments. */
-#define NF_VERDICT_MASK 0x0000ffff
-#define NF_VERDICT_BITS 16
+ * number or errno values. Not nice, but better than additional function
+ * arguments. */
+#define NF_VERDICT_MASK 0x000000ff
 
+/* extra verdict flags have mask 0x0000ff00 */
+#define NF_VERDICT_FLAG_QUEUE_BYPASS	0x00008000
+
+/* queue number (NF_QUEUE) or errno (NF_DROP) */
 #define NF_VERDICT_QMASK 0xffff0000
 #define NF_VERDICT_QBITS 16
 
-#define NF_QUEUE_NR(x) ((((x) << NF_VERDICT_BITS) & NF_VERDICT_QMASK) | NF_QUEUE)
+#define NF_QUEUE_NR(x) ((((x) << 16) & NF_VERDICT_QMASK) | NF_QUEUE)
 
-#define NF_DROP_ERR(x) (((-x) << NF_VERDICT_BITS) | NF_DROP)
+#define NF_DROP_ERR(x) (((-x) << 16) | NF_DROP)
 
 /* only for userspace compatibility */
 #ifndef __KERNEL__
@@ -41,6 +45,9 @@
    <= 0x2000 is used for protocol-flags. */
 #define NFC_UNKNOWN 0x4000
 #define NFC_ALTERED 0x8000
+
+/* NF_VERDICT_BITS should be 8 now, but userspace might break if this changes */
+#define NF_VERDICT_BITS 16
 #endif
 
 enum nf_inet_hooks {
@@ -72,6 +79,10 @@
 
 #ifdef __KERNEL__
 #ifdef CONFIG_NETFILTER
+static inline int NF_DROP_GETERR(int verdict)
+{
+	return -(verdict >> NF_VERDICT_QBITS);
+}
 
 static inline int nf_inet_addr_cmp(const union nf_inet_addr *a1,
 				   const union nf_inet_addr *a2)
diff -dur linux-2.6.32-220.17.1.el6/net/ipv4/netfilter/ip_tables.c linux-2.6.32-220.17.1.el6_patched/net/ipv4/netfilter/ip_tables.c
--- linux-2.6.32-220.17.1.el6/net/ipv4/netfilter/ip_tables.c	2012-04-26 20:49:48.000000000 +0400
+++ linux-2.6.32-220.17.1.el6_patched/net/ipv4/netfilter/ip_tables.c	2012-07-24 12:47:05.739569171 +0400
@@ -421,7 +421,7 @@
 #endif
 		/* Target might have changed stuff. */
 		ip = ip_hdr(skb);
-		if (verdict == IPT_CONTINUE)
+		if (verdict == IPT_CONTINUE || (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
 			e = ipt_next_entry(e);
 		else
 			/* Verdict */
diff -dur linux-2.6.32-220.17.1.el6/net/ipv6/netfilter/ip6_tables.c linux-2.6.32-220.17.1.el6_patched/net/ipv6/netfilter/ip6_tables.c
--- linux-2.6.32-220.17.1.el6/net/ipv6/netfilter/ip6_tables.c	2012-07-24 15:44:04.817581321 +0400
+++ linux-2.6.32-220.17.1.el6_patched/net/ipv6/netfilter/ip6_tables.c	2012-07-24 15:42:51.584580776 +0400
@@ -449,7 +449,7 @@
 		}
 		tb_comefrom = 0x57acc001;
 #endif
-		if (verdict == IP6T_CONTINUE)
+		if (verdict == IP6T_CONTINUE || (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
 			e = ip6t_next_entry(e);
 		else
 			/* Verdict */
diff -dur linux-2.6.32-220.17.1.el6/net/netfilter/core.c linux-2.6.32-220.17.1.el6_patched/net/netfilter/core.c
--- linux-2.6.32-220.17.1.el6/net/netfilter/core.c	2012-04-26 20:51:06.000000000 +0400
+++ linux-2.6.32-220.17.1.el6_patched/net/netfilter/core.c	2012-07-23 17:20:58.000000000 +0400
@@ -176,13 +176,21 @@
 		ret = 1;
 	} else if ((verdict & NF_VERDICT_MASK) == NF_DROP) {
 		kfree_skb(skb);
-		ret = -(verdict >> NF_VERDICT_BITS);
+		ret = NF_DROP_GETERR(verdict);
 		if (ret == 0)
 			ret = -EPERM;
 	} else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) {
-		if (!nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
-			      verdict >> NF_VERDICT_BITS))
-			goto next_hook;
+		int err = nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
+						verdict >> NF_VERDICT_QBITS);
+		if (err < 0) {
+			if (err == -ECANCELED)
+				goto next_hook;
+			if (err == -ESRCH &&
+			   (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
+				goto next_hook;
+			kfree_skb(skb);
+		}
+		ret = 0;
 	}
 	rcu_read_unlock();
 	return ret;
diff -dur linux-2.6.32-220.17.1.el6/net/netfilter/nfnetlink_queue.c linux-2.6.32-220.17.1.el6_patched/net/netfilter/nfnetlink_queue.c
--- linux-2.6.32-220.17.1.el6/net/netfilter/nfnetlink_queue.c	2009-12-03 06:51:21.000000000 +0300
+++ linux-2.6.32-220.17.1.el6_patched/net/netfilter/nfnetlink_queue.c	2012-07-19 16:12:50.000000000 +0400
@@ -391,24 +391,32 @@
 {
 	struct sk_buff *nskb;
 	struct nfqnl_instance *queue;
-	int err;
+	int err = -ENOBUFS;
 
 	/* rcu_read_lock()ed by nf_hook_slow() */
 	queue = instance_lookup(queuenum);
-	if (!queue)
+	if (!queue) {
+		err = -ESRCH;
 		goto err_out;
+	}
 
-	if (queue->copy_mode == NFQNL_COPY_NONE)
+	if (queue->copy_mode == NFQNL_COPY_NONE) {
+		err = -EINVAL;
 		goto err_out;
+	}
 
 	nskb = nfqnl_build_packet_message(queue, entry);
-	if (nskb == NULL)
+	if (nskb == NULL) {
+		err = -ENOMEM;
 		goto err_out;
+	}
 
 	spin_lock_bh(&queue->lock);
 
-	if (!queue->peer_pid)
+	if (!queue->peer_pid) {
+		err = -EINVAL;
 		goto err_out_free_nskb;
+	}
 
 	if (queue->queue_total >= queue->queue_maxlen) {
 		queue->queue_dropped++;
@@ -436,7 +444,7 @@
 err_out_unlock:
 	spin_unlock_bh(&queue->lock);
 err_out:
-	return -1;
+	return err;
 }
 
 static int
diff -dur linux-2.6.32-220.17.1.el6/net/netfilter/nf_queue.c linux-2.6.32-220.17.1.el6_patched/net/netfilter/nf_queue.c
--- linux-2.6.32-220.17.1.el6/net/netfilter/nf_queue.c	2009-12-03 06:51:21.000000000 +0300
+++ linux-2.6.32-220.17.1.el6_patched/net/netfilter/nf_queue.c	2012-07-19 16:24:26.000000000 +0400
@@ -113,7 +113,7 @@
 		      int (*okfn)(struct sk_buff *),
 		      unsigned int queuenum)
 {
-	int status;
+	int status = -ENOENT;
 	struct nf_queue_entry *entry = NULL;
 #ifdef CONFIG_BRIDGE_NETFILTER
 	struct net_device *physindev;
@@ -126,16 +126,20 @@
 	rcu_read_lock();
 
 	qh = rcu_dereference(queue_handler[pf]);
-	if (!qh)
+	if (!qh) {
+		status = -ESRCH;
 		goto err_unlock;
+	}
 
 	afinfo = nf_get_afinfo(pf);
 	if (!afinfo)
 		goto err_unlock;
 
 	entry = kmalloc(sizeof(*entry) + afinfo->route_key_size, GFP_ATOMIC);
-	if (!entry)
+	if (!entry) {
+		status = -ENOMEM;
 		goto err_unlock;
+	}
 
 	*entry = (struct nf_queue_entry) {
 		.skb	= skb,
@@ -149,9 +153,8 @@
 
 	/* If it's going away, ignore hook. */
 	if (!try_module_get(entry->elem->owner)) {
-		rcu_read_unlock();
-		kfree(entry);
-		return 0;
+		status = -ECANCELED;
+		goto err_unlock;
 	}
 
 	/* Bump dev refs so they don't vanish while packet is out */
@@ -179,14 +182,13 @@
 		goto err;
 	}
 
-	return 1;
+	return 0;
 
 err_unlock:
 	rcu_read_unlock();
 err:
-	kfree_skb(skb);
 	kfree(entry);
-	return 1;
+	return status;
 }
 
 int nf_queue(struct sk_buff *skb,
@@ -198,6 +200,8 @@
 	     unsigned int queuenum)
 {
 	struct sk_buff *segs;
+	int err;
+	unsigned int queued;
 
 	if (!skb_is_gso(skb))
 		return __nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
@@ -213,20 +217,35 @@
 	}
 
 	segs = skb_gso_segment(skb, 0);
-	kfree_skb(skb);
+	/* Does not use PTR_ERR to limit the number of error codes that can be
+	 * returned by nf_queue.  For instance, callers rely on -ECANCELED to mean
+	 * 'ignore this hook'.
+	 */
 	if (IS_ERR(segs))
-		return 1;
+		return -EINVAL;
 
+	queued = 0;
+	err = 0;
 	do {
 		struct sk_buff *nskb = segs->next;
 
 		segs->next = NULL;
-		if (!__nf_queue(segs, elem, pf, hook, indev, outdev, okfn,
-				queuenum))
+		if (err == 0)
+			err = __nf_queue(segs, elem, pf, hook, indev,
+					   outdev, okfn, queuenum);
+		if (err == 0)
+			queued++;
+		else
 			kfree_skb(segs);
 		segs = nskb;
 	} while (segs);
-	return 1;
+
+	/* also free orig skb if only some segments were queued */
+	if (unlikely(err && queued))
+		err = 0;
+	if (err == 0)
+		kfree_skb(skb);
+	return err;
 }
 
 void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
@@ -234,6 +253,7 @@
 	struct sk_buff *skb = entry->skb;
 	struct list_head *elem = &entry->elem->list;
 	const struct nf_afinfo *afinfo;
+	int err;
 
 	rcu_read_lock();
 
@@ -268,10 +288,17 @@
 	case NF_STOLEN:
 		break;
 	case NF_QUEUE:
-		if (!__nf_queue(skb, elem, entry->pf, entry->hook,
-				entry->indev, entry->outdev, entry->okfn,
-				verdict >> NF_VERDICT_BITS))
-			goto next_hook;
+		err = __nf_queue(skb, elem, entry->pf, entry->hook,
+				 entry->indev, entry->outdev, entry->okfn,
+				 verdict >> NF_VERDICT_QBITS);
+		if (err < 0) {
+			if (err == -ECANCELED)
+				goto next_hook;
+			if (err == -ESRCH &&
+			   (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
+				goto next_hook;
+			kfree_skb(skb);
+		}
 		break;
 	default:
 		kfree_skb(skb);
diff -dur linux-2.6.32-220.17.1.el6/net/netfilter/xt_NFQUEUE.c linux-2.6.32-220.17.1.el6_patched/net/netfilter/xt_NFQUEUE.c
--- linux-2.6.32-220.17.1.el6/net/netfilter/xt_NFQUEUE.c	2009-12-03 06:51:21.000000000 +0300
+++ linux-2.6.32-220.17.1.el6_patched/net/netfilter/xt_NFQUEUE.c	2012-07-24 15:02:22.338243642 +0400
@@ -48,17 +48,6 @@
 	return jhash_2words((__force u32)ipaddr, iph->protocol, jhash_initval);
 }
 
-static unsigned int
-nfqueue_tg4_v1(struct sk_buff *skb, const struct xt_target_param *par)
-{
-	const struct xt_NFQ_info_v1 *info = par->targinfo;
-	u32 queue = info->queuenum;
-
-	if (info->queues_total > 1)
-		queue = hash_v4(skb) % info->queues_total + queue;
-	return NF_QUEUE_NR(queue);
-}
-
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
 static u32 hash_v6(const struct sk_buff *skb)
 {
@@ -72,22 +61,39 @@
 
 	return jhash2((__force u32 *)addr, ARRAY_SIZE(addr), jhash_initval);
 }
+#endif
 
 static unsigned int
-nfqueue_tg6_v1(struct sk_buff *skb, const struct xt_target_param *par)
+nfqueue_tg_v1(struct sk_buff *skb, const struct xt_target_param *par)
 {
 	const struct xt_NFQ_info_v1 *info = par->targinfo;
 	u32 queue = info->queuenum;
 
-	if (info->queues_total > 1)
-		queue = hash_v6(skb) % info->queues_total + queue;
+	if (info->queues_total > 1) {
+		if (par->family == NFPROTO_IPV4)
+			queue = hash_v4(skb) % info->queues_total + queue;
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
+		else if (par->family == NFPROTO_IPV6)
+			queue = hash_v6(skb) % info->queues_total + queue;
+#endif
+	}
 	return NF_QUEUE_NR(queue);
 }
-#endif
 
-static bool nfqueue_tg_v1_check(const struct xt_tgchk_param *par)
+static unsigned int
+nfqueue_tg_v2(struct sk_buff *skb, const struct xt_target_param *par)
 {
-	const struct xt_NFQ_info_v1 *info = par->targinfo;
+	const struct xt_NFQ_info_v2 *info = par->targinfo;
+	unsigned int ret = nfqueue_tg_v1(skb, par);
+
+	if (info->bypass)
+		ret |= NF_VERDICT_FLAG_QUEUE_BYPASS;
+	return ret;
+}
+
+static bool nfqueue_tg_check(const struct xt_tgchk_param *par)
+{
+	const struct xt_NFQ_info_v2 *info = par->targinfo;
 	u32 maxid;
 
 	if (info->queues_total == 0) {
@@ -100,6 +106,8 @@
 		       info->queues_total, maxid);
 		return false;
 	}
+	if (par->target->revision == 2 && info->bypass > 1)
+		return false;
 	return true;
 }
 
@@ -114,23 +122,21 @@
 	{
 		.name		= "NFQUEUE",
 		.revision	= 1,
-		.family		= NFPROTO_IPV4,
-		.checkentry	= nfqueue_tg_v1_check,
-		.target		= nfqueue_tg4_v1,
+		.family		= NFPROTO_UNSPEC,
+		.checkentry	= nfqueue_tg_check,
+		.target		= nfqueue_tg_v1,
 		.targetsize	= sizeof(struct xt_NFQ_info_v1),
 		.me		= THIS_MODULE,
 	},
-#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
 	{
 		.name		= "NFQUEUE",
-		.revision	= 1,
-		.family		= NFPROTO_IPV6,
-		.checkentry	= nfqueue_tg_v1_check,
-		.target		= nfqueue_tg6_v1,
-		.targetsize	= sizeof(struct xt_NFQ_info_v1),
+		.revision	= 2,
+		.family		= NFPROTO_UNSPEC,
+		.checkentry	= nfqueue_tg_check,
+		.target		= nfqueue_tg_v2,
+		.targetsize	= sizeof(struct xt_NFQ_info_v2),
 		.me		= THIS_MODULE,
 	},
-#endif
 };
 
 static int __init nfqueue_tg_init(void)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: RHEL backported '--queue-bypass'
  2012-07-24 12:11 RHEL backported '--queue-bypass' kay
@ 2012-07-25  9:21 ` kay
  2012-07-29 16:30   ` Jan Engelhardt
  0 siblings, 1 reply; 8+ messages in thread
From: kay @ 2012-07-25  9:21 UTC (permalink / raw)
  To: netfilter

[-- Attachment #1: Type: text/plain, Size: 924 bytes --]

The http://bugzilla.netfilter.org/show_bug.cgi?id=778 patch is wrong,
I should not have to use it. Please ignore it.

The updated patch is attached.

2012/7/24 kay <kay.diam@gmail.com>:
> Hello,
>
> I've backported 'queue bypass' patch from 2.6.39 to RHEL 2.6.32 kernel
> (centos6.2). Many thanks to Florian Westphal.
>
> The origin patches I used:
> https://git.netfilter.org/cgi-bin/gitweb.cgi?p=iptables.git;a=commit;h=6924b4987d88fbe383bec4da4cf331cc466c245e
> https://git.netfilter.org/cgi-bin/gitweb.cgi?p=iptables.git;a=commit;h=3c461ceeed5f55599930051f6feaec014b08f730
> http://bugzilla.netfilter.org/show_bug.cgi?id=778
> http://thread.gmane.org/gmane.linux.network/184302/focus=184239 (patches 72-75)
>
> Patches attached are ready to be applied by rpmbuild spec.
>
> It works fine for me but I would like to publish it for review. Maybe
> someone needs this functionality too or will find some bugs.
>
> Regards.

[-- Attachment #2: linux-kernel-queue_bypass.patch --]
[-- Type: application/octet-stream, Size: 11083 bytes --]

diff -dur linux-2.6.32-220.17.1.el6/include/linux/netfilter/xt_NFQUEUE.h linux-2.6.32-220.17.1.el6_patched/include/linux/netfilter/xt_NFQUEUE.h
--- linux-2.6.32-220.17.1.el6/include/linux/netfilter/xt_NFQUEUE.h	2009-12-03 06:51:21.000000000 +0300
+++ linux-2.6.32-220.17.1.el6_patched/include/linux/netfilter/xt_NFQUEUE.h	2012-07-19 16:22:17.000000000 +0400
@@ -20,4 +20,10 @@
 	__u16 queues_total;
 };
 
+struct xt_NFQ_info_v2 {
+	__u16 queuenum;
+	__u16 queues_total;
+	__u16 bypass;
+};
+
 #endif /* _XT_NFQ_TARGET_H */
diff -dur linux-2.6.32-220.17.1.el6/include/linux/netfilter.h linux-2.6.32-220.17.1.el6_patched/include/linux/netfilter.h
--- linux-2.6.32-220.17.1.el6/include/linux/netfilter.h	2012-04-26 20:51:06.000000000 +0400
+++ linux-2.6.32-220.17.1.el6_patched/include/linux/netfilter.h	2012-07-19 16:21:24.000000000 +0400
@@ -24,16 +24,20 @@
 #define NF_MAX_VERDICT NF_STOP
 
 /* we overload the higher bits for encoding auxiliary data such as the queue
- * number. Not nice, but better than additional function arguments. */
-#define NF_VERDICT_MASK 0x0000ffff
-#define NF_VERDICT_BITS 16
+ * number or errno values. Not nice, but better than additional function
+ * arguments. */
+#define NF_VERDICT_MASK 0x000000ff
 
+/* extra verdict flags have mask 0x0000ff00 */
+#define NF_VERDICT_FLAG_QUEUE_BYPASS	0x00008000
+
+/* queue number (NF_QUEUE) or errno (NF_DROP) */
 #define NF_VERDICT_QMASK 0xffff0000
 #define NF_VERDICT_QBITS 16
 
-#define NF_QUEUE_NR(x) ((((x) << NF_VERDICT_BITS) & NF_VERDICT_QMASK) | NF_QUEUE)
+#define NF_QUEUE_NR(x) ((((x) << 16) & NF_VERDICT_QMASK) | NF_QUEUE)
 
-#define NF_DROP_ERR(x) (((-x) << NF_VERDICT_BITS) | NF_DROP)
+#define NF_DROP_ERR(x) (((-x) << 16) | NF_DROP)
 
 /* only for userspace compatibility */
 #ifndef __KERNEL__
@@ -41,6 +45,9 @@
    <= 0x2000 is used for protocol-flags. */
 #define NFC_UNKNOWN 0x4000
 #define NFC_ALTERED 0x8000
+
+/* NF_VERDICT_BITS should be 8 now, but userspace might break if this changes */
+#define NF_VERDICT_BITS 16
 #endif
 
 enum nf_inet_hooks {
@@ -72,6 +79,10 @@
 
 #ifdef __KERNEL__
 #ifdef CONFIG_NETFILTER
+static inline int NF_DROP_GETERR(int verdict)
+{
+	return -(verdict >> NF_VERDICT_QBITS);
+}
 
 static inline int nf_inet_addr_cmp(const union nf_inet_addr *a1,
 				   const union nf_inet_addr *a2)
diff -dur linux-2.6.32-220.17.1.el6/net/netfilter/core.c linux-2.6.32-220.17.1.el6_patched/net/netfilter/core.c
--- linux-2.6.32-220.17.1.el6/net/netfilter/core.c	2012-04-26 20:51:06.000000000 +0400
+++ linux-2.6.32-220.17.1.el6_patched/net/netfilter/core.c	2012-07-23 17:20:58.000000000 +0400
@@ -176,13 +176,21 @@
 		ret = 1;
 	} else if ((verdict & NF_VERDICT_MASK) == NF_DROP) {
 		kfree_skb(skb);
-		ret = -(verdict >> NF_VERDICT_BITS);
+		ret = NF_DROP_GETERR(verdict);
 		if (ret == 0)
 			ret = -EPERM;
 	} else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) {
-		if (!nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
-			      verdict >> NF_VERDICT_BITS))
-			goto next_hook;
+		int err = nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
+						verdict >> NF_VERDICT_QBITS);
+		if (err < 0) {
+			if (err == -ECANCELED)
+				goto next_hook;
+			if (err == -ESRCH &&
+			   (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
+				goto next_hook;
+			kfree_skb(skb);
+		}
+		ret = 0;
 	}
 	rcu_read_unlock();
 	return ret;
diff -dur linux-2.6.32-220.17.1.el6/net/netfilter/nfnetlink_queue.c linux-2.6.32-220.17.1.el6_patched/net/netfilter/nfnetlink_queue.c
--- linux-2.6.32-220.17.1.el6/net/netfilter/nfnetlink_queue.c	2009-12-03 06:51:21.000000000 +0300
+++ linux-2.6.32-220.17.1.el6_patched/net/netfilter/nfnetlink_queue.c	2012-07-19 16:12:50.000000000 +0400
@@ -391,24 +391,32 @@
 {
 	struct sk_buff *nskb;
 	struct nfqnl_instance *queue;
-	int err;
+	int err = -ENOBUFS;
 
 	/* rcu_read_lock()ed by nf_hook_slow() */
 	queue = instance_lookup(queuenum);
-	if (!queue)
+	if (!queue) {
+		err = -ESRCH;
 		goto err_out;
+	}
 
-	if (queue->copy_mode == NFQNL_COPY_NONE)
+	if (queue->copy_mode == NFQNL_COPY_NONE) {
+		err = -EINVAL;
 		goto err_out;
+	}
 
 	nskb = nfqnl_build_packet_message(queue, entry);
-	if (nskb == NULL)
+	if (nskb == NULL) {
+		err = -ENOMEM;
 		goto err_out;
+	}
 
 	spin_lock_bh(&queue->lock);
 
-	if (!queue->peer_pid)
+	if (!queue->peer_pid) {
+		err = -EINVAL;
 		goto err_out_free_nskb;
+	}
 
 	if (queue->queue_total >= queue->queue_maxlen) {
 		queue->queue_dropped++;
@@ -436,7 +444,7 @@
 err_out_unlock:
 	spin_unlock_bh(&queue->lock);
 err_out:
-	return -1;
+	return err;
 }
 
 static int
diff -dur linux-2.6.32-220.17.1.el6/net/netfilter/nf_queue.c linux-2.6.32-220.17.1.el6_patched/net/netfilter/nf_queue.c
--- linux-2.6.32-220.17.1.el6/net/netfilter/nf_queue.c	2009-12-03 06:51:21.000000000 +0300
+++ linux-2.6.32-220.17.1.el6_patched/net/netfilter/nf_queue.c	2012-07-19 16:24:26.000000000 +0400
@@ -113,7 +113,7 @@
 		      int (*okfn)(struct sk_buff *),
 		      unsigned int queuenum)
 {
-	int status;
+	int status = -ENOENT;
 	struct nf_queue_entry *entry = NULL;
 #ifdef CONFIG_BRIDGE_NETFILTER
 	struct net_device *physindev;
@@ -126,16 +126,20 @@
 	rcu_read_lock();
 
 	qh = rcu_dereference(queue_handler[pf]);
-	if (!qh)
+	if (!qh) {
+		status = -ESRCH;
 		goto err_unlock;
+	}
 
 	afinfo = nf_get_afinfo(pf);
 	if (!afinfo)
 		goto err_unlock;
 
 	entry = kmalloc(sizeof(*entry) + afinfo->route_key_size, GFP_ATOMIC);
-	if (!entry)
+	if (!entry) {
+		status = -ENOMEM;
 		goto err_unlock;
+	}
 
 	*entry = (struct nf_queue_entry) {
 		.skb	= skb,
@@ -149,9 +153,8 @@
 
 	/* If it's going away, ignore hook. */
 	if (!try_module_get(entry->elem->owner)) {
-		rcu_read_unlock();
-		kfree(entry);
-		return 0;
+		status = -ECANCELED;
+		goto err_unlock;
 	}
 
 	/* Bump dev refs so they don't vanish while packet is out */
@@ -179,14 +182,13 @@
 		goto err;
 	}
 
-	return 1;
+	return 0;
 
 err_unlock:
 	rcu_read_unlock();
 err:
-	kfree_skb(skb);
 	kfree(entry);
-	return 1;
+	return status;
 }
 
 int nf_queue(struct sk_buff *skb,
@@ -198,6 +200,8 @@
 	     unsigned int queuenum)
 {
 	struct sk_buff *segs;
+	int err;
+	unsigned int queued;
 
 	if (!skb_is_gso(skb))
 		return __nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
@@ -213,20 +217,35 @@
 	}
 
 	segs = skb_gso_segment(skb, 0);
-	kfree_skb(skb);
+	/* Does not use PTR_ERR to limit the number of error codes that can be
+	 * returned by nf_queue.  For instance, callers rely on -ECANCELED to mean
+	 * 'ignore this hook'.
+	 */
 	if (IS_ERR(segs))
-		return 1;
+		return -EINVAL;
 
+	queued = 0;
+	err = 0;
 	do {
 		struct sk_buff *nskb = segs->next;
 
 		segs->next = NULL;
-		if (!__nf_queue(segs, elem, pf, hook, indev, outdev, okfn,
-				queuenum))
+		if (err == 0)
+			err = __nf_queue(segs, elem, pf, hook, indev,
+					   outdev, okfn, queuenum);
+		if (err == 0)
+			queued++;
+		else
 			kfree_skb(segs);
 		segs = nskb;
 	} while (segs);
-	return 1;
+
+	/* also free orig skb if only some segments were queued */
+	if (unlikely(err && queued))
+		err = 0;
+	if (err == 0)
+		kfree_skb(skb);
+	return err;
 }
 
 void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
@@ -234,6 +253,7 @@
 	struct sk_buff *skb = entry->skb;
 	struct list_head *elem = &entry->elem->list;
 	const struct nf_afinfo *afinfo;
+	int err;
 
 	rcu_read_lock();
 
@@ -268,10 +288,17 @@
 	case NF_STOLEN:
 		break;
 	case NF_QUEUE:
-		if (!__nf_queue(skb, elem, entry->pf, entry->hook,
-				entry->indev, entry->outdev, entry->okfn,
-				verdict >> NF_VERDICT_BITS))
-			goto next_hook;
+		err = __nf_queue(skb, elem, entry->pf, entry->hook,
+				 entry->indev, entry->outdev, entry->okfn,
+				 verdict >> NF_VERDICT_QBITS);
+		if (err < 0) {
+			if (err == -ECANCELED)
+				goto next_hook;
+			if (err == -ESRCH &&
+			   (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
+				goto next_hook;
+			kfree_skb(skb);
+		}
 		break;
 	default:
 		kfree_skb(skb);
diff -dur linux-2.6.32-220.17.1.el6/net/netfilter/xt_NFQUEUE.c linux-2.6.32-220.17.1.el6_patched/net/netfilter/xt_NFQUEUE.c
--- linux-2.6.32-220.17.1.el6/net/netfilter/xt_NFQUEUE.c	2009-12-03 06:51:21.000000000 +0300
+++ linux-2.6.32-220.17.1.el6_patched/net/netfilter/xt_NFQUEUE.c	2012-07-24 15:02:22.338243642 +0400
@@ -48,17 +48,6 @@
 	return jhash_2words((__force u32)ipaddr, iph->protocol, jhash_initval);
 }
 
-static unsigned int
-nfqueue_tg4_v1(struct sk_buff *skb, const struct xt_target_param *par)
-{
-	const struct xt_NFQ_info_v1 *info = par->targinfo;
-	u32 queue = info->queuenum;
-
-	if (info->queues_total > 1)
-		queue = hash_v4(skb) % info->queues_total + queue;
-	return NF_QUEUE_NR(queue);
-}
-
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
 static u32 hash_v6(const struct sk_buff *skb)
 {
@@ -72,22 +61,39 @@
 
 	return jhash2((__force u32 *)addr, ARRAY_SIZE(addr), jhash_initval);
 }
+#endif
 
 static unsigned int
-nfqueue_tg6_v1(struct sk_buff *skb, const struct xt_target_param *par)
+nfqueue_tg_v1(struct sk_buff *skb, const struct xt_target_param *par)
 {
 	const struct xt_NFQ_info_v1 *info = par->targinfo;
 	u32 queue = info->queuenum;
 
-	if (info->queues_total > 1)
-		queue = hash_v6(skb) % info->queues_total + queue;
+	if (info->queues_total > 1) {
+		if (par->family == NFPROTO_IPV4)
+			queue = hash_v4(skb) % info->queues_total + queue;
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
+		else if (par->family == NFPROTO_IPV6)
+			queue = hash_v6(skb) % info->queues_total + queue;
+#endif
+	}
 	return NF_QUEUE_NR(queue);
 }
-#endif
 
-static bool nfqueue_tg_v1_check(const struct xt_tgchk_param *par)
+static unsigned int
+nfqueue_tg_v2(struct sk_buff *skb, const struct xt_target_param *par)
 {
-	const struct xt_NFQ_info_v1 *info = par->targinfo;
+	const struct xt_NFQ_info_v2 *info = par->targinfo;
+	unsigned int ret = nfqueue_tg_v1(skb, par);
+
+	if (info->bypass)
+		ret |= NF_VERDICT_FLAG_QUEUE_BYPASS;
+	return ret;
+}
+
+static bool nfqueue_tg_check(const struct xt_tgchk_param *par)
+{
+	const struct xt_NFQ_info_v2 *info = par->targinfo;
 	u32 maxid;
 
 	if (info->queues_total == 0) {
@@ -100,6 +106,8 @@
 		       info->queues_total, maxid);
 		return false;
 	}
+	if (par->target->revision == 2 && info->bypass > 1)
+		return false;
 	return true;
 }
 
@@ -114,23 +122,21 @@
 	{
 		.name		= "NFQUEUE",
 		.revision	= 1,
-		.family		= NFPROTO_IPV4,
-		.checkentry	= nfqueue_tg_v1_check,
-		.target		= nfqueue_tg4_v1,
+		.family		= NFPROTO_UNSPEC,
+		.checkentry	= nfqueue_tg_check,
+		.target		= nfqueue_tg_v1,
 		.targetsize	= sizeof(struct xt_NFQ_info_v1),
 		.me		= THIS_MODULE,
 	},
-#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
 	{
 		.name		= "NFQUEUE",
-		.revision	= 1,
-		.family		= NFPROTO_IPV6,
-		.checkentry	= nfqueue_tg_v1_check,
-		.target		= nfqueue_tg6_v1,
-		.targetsize	= sizeof(struct xt_NFQ_info_v1),
+		.revision	= 2,
+		.family		= NFPROTO_UNSPEC,
+		.checkentry	= nfqueue_tg_check,
+		.target		= nfqueue_tg_v2,
+		.targetsize	= sizeof(struct xt_NFQ_info_v2),
 		.me		= THIS_MODULE,
 	},
-#endif
 };
 
 static int __init nfqueue_tg_init(void)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: RHEL backported '--queue-bypass'
  2012-07-25  9:21 ` kay
@ 2012-07-29 16:30   ` Jan Engelhardt
  2012-07-29 16:42     ` kay
  0 siblings, 1 reply; 8+ messages in thread
From: Jan Engelhardt @ 2012-07-29 16:30 UTC (permalink / raw)
  To: kay; +Cc: netfilter

On Wednesday 2012-07-25 11:21, kay wrote:

>The http://bugzilla.netfilter.org/show_bug.cgi?id=778 patch is wrong,
>I should not have to use it. Please ignore it.

In general, it is easier to just ship a new iptables version. Like Linux 
kernels, having something that has pretty much the same stability level 
at every release is a good approach.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: RHEL backported '--queue-bypass'
  2012-07-29 16:30   ` Jan Engelhardt
@ 2012-07-29 16:42     ` kay
  2012-07-29 17:37       ` Jan Engelhardt
  0 siblings, 1 reply; 8+ messages in thread
From: kay @ 2012-07-29 16:42 UTC (permalink / raw)
  To: netfilter

New iptables require new kernels, new kernels require recompiling lots
of system soft. Back porting was the optimal solution.

2012/7/29 Jan Engelhardt <jengelh@inai.de>:
> On Wednesday 2012-07-25 11:21, kay wrote:
>
>>The http://bugzilla.netfilter.org/show_bug.cgi?id=778 patch is wrong,
>>I should not have to use it. Please ignore it.
>
> In general, it is easier to just ship a new iptables version. Like Linux
> kernels, having something that has pretty much the same stability level
> at every release is a good approach.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: RHEL backported '--queue-bypass'
  2012-07-29 16:42     ` kay
@ 2012-07-29 17:37       ` Jan Engelhardt
  2012-07-29 17:52         ` kay
  0 siblings, 1 reply; 8+ messages in thread
From: Jan Engelhardt @ 2012-07-29 17:37 UTC (permalink / raw)
  To: kay; +Cc: netfilter

On Sunday 2012-07-29 18:42, kay wrote:

>New iptables require new kernels

No it does not.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: RHEL backported '--queue-bypass'
  2012-07-29 17:37       ` Jan Engelhardt
@ 2012-07-29 17:52         ` kay
  2012-07-29 18:11           ` Jan Engelhardt
  0 siblings, 1 reply; 8+ messages in thread
From: kay @ 2012-07-29 17:52 UTC (permalink / raw)
  To: netfilter

Do you mean that if I compile latest iptables for 2.6.32 kernel
everything will work?

2012/7/29 Jan Engelhardt <jengelh@inai.de>:
> On Sunday 2012-07-29 18:42, kay wrote:
>
>>New iptables require new kernels
>
> No it does not.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: RHEL backported '--queue-bypass'
  2012-07-29 17:52         ` kay
@ 2012-07-29 18:11           ` Jan Engelhardt
  2012-07-30  5:07             ` kay
  0 siblings, 1 reply; 8+ messages in thread
From: Jan Engelhardt @ 2012-07-29 18:11 UTC (permalink / raw)
  To: kay; +Cc: netfilter

On Sunday 2012-07-29 19:52, kay wrote:

>Do you mean that if I compile latest iptables for 2.6.32 kernel
>everything will work?

Where does it say that it would not?
It should even work with linux 2.4 (once you got it compiled), but we 
don't bother testing that old piece of software.

Do you actually work for Redhat or how did it came you came about with 
"RHEL backported --queue-bypass"?

Oh, and in these circles of Internet, we don't top-post like you did.

>
>2012/7/29 Jan Engelhardt <jengelh@inai.de>:
>> On Sunday 2012-07-29 18:42, kay wrote:
>>
>>>New iptables require new kernels
>>
>> No it does not.
>--
>To unsubscribe from this list: send the line "unsubscribe netfilter" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: RHEL backported '--queue-bypass'
  2012-07-29 18:11           ` Jan Engelhardt
@ 2012-07-30  5:07             ` kay
  0 siblings, 0 replies; 8+ messages in thread
From: kay @ 2012-07-30  5:07 UTC (permalink / raw)
  To: netfilter

I have asked Florian how to backport that functionality and he
provided me with the  origin kernel patches, so I'm not sure that new
iptables rule will work on old kernel. Anyway I got extra skills.

As for the topic theme, that's my poor english, I'm not working on
redhat, just use their kernel. Sorry for confusing.

Regards.

2012/7/29 Jan Engelhardt <jengelh@inai.de>:
> On Sunday 2012-07-29 19:52, kay wrote:
>
>>Do you mean that if I compile latest iptables for 2.6.32 kernel
>>everything will work?
>
> Where does it say that it would not?
> It should even work with linux 2.4 (once you got it compiled), but we
> don't bother testing that old piece of software.
>
> Do you actually work for Redhat or how did it came you came about with
> "RHEL backported --queue-bypass"?
>
> Oh, and in these circles of Internet, we don't top-post like you did.
>
>>
>>2012/7/29 Jan Engelhardt <jengelh@inai.de>:
>>> On Sunday 2012-07-29 18:42, kay wrote:
>>>
>>>>New iptables require new kernels
>>>
>>> No it does not.
>>--
>>To unsubscribe from this list: send the line "unsubscribe netfilter" in
>>the body of a message to majordomo@vger.kernel.org
>>More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2012-07-30  5:07 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-24 12:11 RHEL backported '--queue-bypass' kay
2012-07-25  9:21 ` kay
2012-07-29 16:30   ` Jan Engelhardt
2012-07-29 16:42     ` kay
2012-07-29 17:37       ` Jan Engelhardt
2012-07-29 17:52         ` kay
2012-07-29 18:11           ` Jan Engelhardt
2012-07-30  5:07             ` kay

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.