Skip to contentSkip to conversation

extensions: libxt_NFQUEUE: Add translation to nft

PATCH In review Shivani Bhardwaj 2 participants 4 messages Dec 21, 2015 – Dec 22, 2015 netfilter

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 extensions: libxt_NFQUEUE: Add translation to nft

Add translation of NF queue to nftables.

Examples:

$ sudo iptables-translate -t nat -A PREROUTING -p tcp --dport 80 -j NFQUEUE --queue-num 30
nft add rule ip nat PREROUTING tcp dport 80 counter  queue num 30
$ sudo iptables-translate -A FORWARD -j NFQUEUE --queue-num 0 --queue-bypass -p TCP --sport 80
nft add rule ip filter FORWARD tcp sport 80 counter  queue num 0 bypass
$ sudo iptables-translate -A FORWARD -j NFQUEUE --queue-balance 0:3
nft add rule ip filter FORWARD counter  queue num 0-3 fanout
$ sudo iptables-translate -A FORWARD -j NFQUEUE --queue-bypass -p TCP --sport 80 --queue-balance 0:3
nft add rule ip filter FORWARD tcp sport 80 counter  queue num 0-3 fanout bypass
---
 extensions/libxt_NFQUEUE.c | 90 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 75 insertions(+), 15 deletions(-)
extensions/libxt_NFQUEUE.c +75 -15
index 0c86918..dd9056d 100644
@@ -21,10 +21,9 @@ enum {
 
 static void NFQUEUE_help(void)
 {
-	printf(
-"NFQUEUE target options\n"
+	printf("NFQUEUE target options\n"
 "  --queue-num value		Send packet to QUEUE number <value>.\n"
-"  		                Valid queue numbers are 0-65535\n"
+"				Valid queue numbers are 0-65535\n"
 );
 }
 
@@ -84,8 +83,8 @@ static void NFQUEUE_parse_v1(struct xt_option_call *cb)
 			xtables_error(PARAMETER_PROBLEM,
 				"Bad range \"%s\"", cb->arg);
 		if (r[0] >= r[1])
-			xtables_error(PARAMETER_PROBLEM, "%u should be less than %u",
-				r[0], r[1]);
+			xtables_error(PARAMETER_PROBLEM,
+				      "%u should be less than %u", r[0], r[1]);
 		info->queuenum = r[0];
 		info->queues_total = r[1] - r[0] + 1;
 		break;
@@ -117,7 +116,7 @@ static void NFQUEUE_parse_v3(struct xt_option_call *cb)
 }
 
 static void NFQUEUE_print(const void *ip,
-                          const struct xt_entry_target *target, int numeric)
+			  const struct xt_entry_target *target, int numeric)
 {
 	const struct xt_NFQ_info *tinfo =
 		(const struct xt_NFQ_info *)target->data;
@@ -125,7 +124,7 @@ static void NFQUEUE_print(const void *ip,
 }
 
 static void NFQUEUE_print_v1(const void *ip,
-                             const struct xt_entry_target *target, int numeric)
+			     const struct xt_entry_target *target, int numeric)
 {
 	const struct xt_NFQ_info_v1 *tinfo = (const void *)target->data;
 	unsigned int last = tinfo->queues_total;
@@ -139,7 +138,7 @@ static void NFQUEUE_print_v1(const void *ip,
 }
 
 static void NFQUEUE_print_v2(const void *ip,
-                             const struct xt_entry_target *target, int numeric)
+			     const struct xt_entry_target *target, int numeric)
 {
 	const struct xt_NFQ_info_v2 *info = (void *) target->data;
 
@@ -149,7 +148,7 @@ static void NFQUEUE_print_v2(const void *ip,
 }
 
 static void NFQUEUE_print_v3(const void *ip,
-                             const struct xt_entry_target *target, int numeric)
+			     const struct xt_entry_target *target, int numeric)
 {
 	const struct xt_NFQ_info_v3 *info = (void *)target->data;
 
@@ -166,7 +165,8 @@ static void NFQUEUE_save(const void *ip, const struct xt_entry_target *target)
 	printf(" --queue-num %u", tinfo->queuenum);
 }
 
-static void NFQUEUE_save_v1(const void *ip, const struct xt_entry_target *target)
+static void
+NFQUEUE_save_v1(const void *ip, const struct xt_entry_target *target)
 {
 	const struct xt_NFQ_info_v1 *tinfo = (const void *)target->data;
 	unsigned int last = tinfo->queues_total;
@@ -179,7 +179,8 @@ static void NFQUEUE_save_v1(const void *ip, const struct xt_entry_target *target
 	}
 }
 
-static void NFQUEUE_save_v2(const void *ip, const struct xt_entry_target *target)
+static void
+NFQUEUE_save_v2(const void *ip, const struct xt_entry_target *target)
 {
 	const struct xt_NFQ_info_v2 *info = (void *) target->data;
 
@@ -202,9 +203,64 @@ static void NFQUEUE_save_v3(const void *ip,
 static void NFQUEUE_init_v1(struct xt_entry_target *t)
 {
 	struct xt_NFQ_info_v1 *tinfo = (void *)t->data;
+
 	tinfo->queues_total = 1;
 }
 
+static int NFQUEUE_xlate(const struct xt_entry_target *target,
+			 struct xt_buf *buf, int numeric)
+{
+	const struct xt_NFQ_info *tinfo =
+		(const struct xt_NFQ_info *)target->data;
+
+	xt_buf_add(buf, " queue num %u", tinfo->queuenum);
+
+	return 1;
+}
+
+static int NFQUEUE_xlate_v1(const struct xt_entry_target *target,
+			    struct xt_buf *buf, int numeric)
+{
+	const struct xt_NFQ_info_v1 *tinfo = (const void *)target->data;
+	unsigned int last = tinfo->queues_total;
+
+	if (last > 1) {
+		last += tinfo->queuenum - 1;
+		xt_buf_add(buf, " queue num %u-%u fanout",
+			   tinfo->queuenum, last);
+	} else {
+		xt_buf_add(buf, " queue num %u", tinfo->queuenum);
+	}
+
+	return 1;
+}
+
+static int NFQUEUE_xlate_v2(const struct xt_entry_target *target,
+			    struct xt_buf *buf, int numeric)
+{
+	const struct xt_NFQ_info_v2 *info = (void *) target->data;
+
+	NFQUEUE_xlate_v1(target, buf, numeric);
+
+	if (info->bypass & NFQ_FLAG_BYPASS)
+		xt_buf_add(buf, " bypass");
+
+	return 1;
+}
+
+static int NFQUEUE_xlate_v3(const struct xt_entry_target *target,
+			    struct xt_buf *buf, int numeric)
+{
+	const struct xt_NFQ_info_v3 *info = (void *)target->data;
+
+	NFQUEUE_xlate_v2(target, buf, numeric);
+
+	if (info->flags & NFQ_FLAG_CPU_FANOUT)
+		xt_buf_add(buf, " fanout");
+
+	return 1;
+}
+
 static struct xtables_target nfqueue_targets[] = {
 {
 	.family		= NFPROTO_UNSPEC,
@@ -216,8 +272,9 @@ static struct xtables_target nfqueue_targets[] = {
 	.print		= NFQUEUE_print,
 	.save		= NFQUEUE_save,
 	.x6_parse	= NFQUEUE_parse,
-	.x6_options	= NFQUEUE_opts
-},{
+	.x6_options	= NFQUEUE_opts,
+	.xlate		= NFQUEUE_xlate,
+}, {
 	.family		= NFPROTO_UNSPEC,
 	.revision	= 1,
 	.name		= "NFQUEUE",
@@ -230,7 +287,8 @@ static struct xtables_target nfqueue_targets[] = {
 	.save		= NFQUEUE_save_v1,
 	.x6_parse	= NFQUEUE_parse_v1,
 	.x6_options	= NFQUEUE_opts,
-},{
+	.xlate		= NFQUEUE_xlate_v1,
+}, {
 	.family		= NFPROTO_UNSPEC,
 	.revision	= 2,
 	.name		= "NFQUEUE",
@@ -243,7 +301,8 @@ static struct xtables_target nfqueue_targets[] = {
 	.save		= NFQUEUE_save_v2,
 	.x6_parse	= NFQUEUE_parse_v2,
 	.x6_options	= NFQUEUE_opts,
-},{
+	.xlate		= NFQUEUE_xlate_v2,
+}, {
 	.family		= NFPROTO_UNSPEC,
 	.revision	= 3,
 	.name		= "NFQUEUE",
@@ -256,6 +315,7 @@ static struct xtables_target nfqueue_targets[] = {
 	.save		= NFQUEUE_save_v3,
 	.x6_parse	= NFQUEUE_parse_v3,
 	.x6_options	= NFQUEUE_opts,
+	.xlate		= NFQUEUE_xlate_v3,
 }
 };
 
Signature · 1 line
1.9.1
#1 lore raw
Quoted 9 lines · Shivani Bhardwaj

Add translation of NF queue to nftables.

Examples:

$ sudo iptables-translate -t nat -A PREROUTING -p tcp --dport 80 -j NFQUEUE --queue-num 30
nft add rule ip nat PREROUTING tcp dport 80 counter  queue num 30
$ sudo iptables-translate -A FORWARD -j NFQUEUE --queue-num 0 --queue-bypass -p TCP --sport 80
nft add rule ip filter FORWARD tcp sport 80 counter  queue num 0 bypass
                                                     ^

Make sure this space is gone in a v2 of this patch.

Quoted 2 lines
$ sudo iptables-translate -A FORWARD -j NFQUEUE --queue-balance 0:3
nft add rule ip filter FORWARD counter  queue num 0-3 fanout

I think --queue-balance is independent from fanout. Check the code and make sure this is correct.

Quoted 2 lines
$ sudo iptables-translate -A FORWARD -j NFQUEUE --queue-bypass -p TCP --sport 80 --queue-balance 0:3
nft add rule ip filter FORWARD tcp sport 80 counter  queue num 0-3 fanout bypass

Although this syntax is correct, we prefer:

nft add rule ip filter FORWARD tcp sport 80 counter queue num 0-3 fanout,bypass
^
comma-separated values for flags.

Thanks.

#2 lore raw
Quoted 10 lines · Pablo Neira Ayuso
Quoted 9 lines · Shivani Bhardwaj

Add translation of NF queue to nftables.

Examples:

$ sudo iptables-translate -t nat -A PREROUTING -p tcp --dport 80 -j NFQUEUE --queue-num 30
nft add rule ip nat PREROUTING tcp dport 80 counter  queue num 30
$ sudo iptables-translate -A FORWARD -j NFQUEUE --queue-num 0 --queue-bypass -p TCP --sport 80
nft add rule ip filter FORWARD tcp sport 80 counter  queue num 0 bypass
Quoted 9 lines
                                                     ^

Make sure this space is gone in a v2 of this patch.

Quoted 2 lines
$ sudo iptables-translate -A FORWARD -j NFQUEUE --queue-balance 0:3
nft add rule ip filter FORWARD counter  queue num 0-3 fanout

I think --queue-balance is independent from fanout. Check the code and make sure this is correct.

Hi,

I have taken reference from here :
http://wiki.nftables.org/wiki-nftables/index.php/Queueing_to_userspace

It says:
When doing load balancing, you can use the fanout option to use the CPU ID as an index to map packets to the queues. The idea is that you can improve performance if there's a queue/userspace application per CPU

Please let me know if I have understood this wrong.

Thank you

Quoted 10 lines
Quoted 2 lines
$ sudo iptables-translate -A FORWARD -j NFQUEUE --queue-bypass -p TCP --sport 80 --queue-balance 0:3
nft add rule ip filter FORWARD tcp sport 80 counter  queue num 0-3 fanout bypass

Although this syntax is correct, we prefer:

nft add rule ip filter FORWARD tcp sport 80 counter queue num 0-3 fanout,bypass
^
comma-separated values for flags.

Thanks.

#3 lore raw
Quoted 25 lines · Shivani Bhardwaj
Quoted 10 lines · Pablo Neira Ayuso
Quoted 9 lines · Shivani Bhardwaj

Add translation of NF queue to nftables.

Examples:

$ sudo iptables-translate -t nat -A PREROUTING -p tcp --dport 80 -j NFQUEUE --queue-num 30
nft add rule ip nat PREROUTING tcp dport 80 counter  queue num 30
$ sudo iptables-translate -A FORWARD -j NFQUEUE --queue-num 0 --queue-bypass -p TCP --sport 80
nft add rule ip filter FORWARD tcp sport 80 counter  queue num 0 bypass
Quoted 9 lines
                                                     ^

Make sure this space is gone in a v2 of this patch.

Quoted 2 lines
$ sudo iptables-translate -A FORWARD -j NFQUEUE --queue-balance 0:3
nft add rule ip filter FORWARD counter  queue num 0-3 fanout

I think --queue-balance is independent from fanout. Check the code and make sure this is correct.

Hi,

I have taken reference from here :
http://wiki.nftables.org/wiki-nftables/index.php/Queueing_to_userspace

Quoted 7 lines

It says:
When doing load balancing, you can use the fanout option to use the CPU ID as an index to map packets to the queues. The idea is that you can improve performance if there's a queue/userspace application per CPU

Please let me know if I have understood this wrong.

I think this description above is not precise, please have a look at:
man iptables-extensions and check NFQUEUE, so you make sure you're interpreting things the right way.

--queue-balance value:value
This specifies a range of queues to use. Packets are then balanced across the given queues. This is useful for multicore systems: start multiple instances of the userspace program on queues x, x+1, .. x+n and use "--queue-balance x:x+n". Packets belonging to the same connection are put into the same nfqueue.

--queue-cpu-fanout
Available starting Linux kernel 3.10. When used together with --queue-balance this will use the CPU ID as an index to map packets to the queues. The idea is that you can improve performance if there's a queue per CPU. This requires --queue-balance to be specified.

So fanout is optional.

You can also fix the wiki to avoid this ambiguity. Thanks.