iptables: add NFQUEUE balancing support
Florian Westphal
maintainerHi,
here is the re-send of the userspace nfqueue changes. Changes since v1:
- re-arranged manpage
- consolidated v1 target into single NFQUEUE_UNSPEC structure (as suggested by Jan).
- use same options for v0 and v1; this will result in a more verbose error when --queue-balance is used with a "NFQUEUE v0 only" kernel (v1 patch would just give a "unkown option" error).
Also available via git, but to ease review I'll send the patches as followup to this mail.
Jozsef just sent a few patches that will most likely cause conflicts with this patchset. I can re-base my patches on top of iptables.git if his patches are applied first, just let me know.
The following changes since commit f9bf812aed50949db584cdf93752193c802fefcb:
Patrick McHardy (1):
Bump version
are available in the git repository at:
git://git.breakpoint.cc/fw/iptables.git nfq_balance
Florian Westphal (2):
libxt_NFQUEUE: use NFPROTO_UNSPEC
libxt_NFQUEUE: add new v1 version with queue-balance option
extensions/libxt_NFQUEUE.c | 119 ++++++++++++++++++++++++++++++---- extensions/libxt_NFQUEUE.man | 18 ++++-- include/linux/netfilter/xt_NFQUEUE.h | 5 ++ 3 files changed, 122 insertions(+), 20 deletions(-)
Florian Westphal
maintainerPATCH 1/1 libxt_NFQUEUE: use NFPROTO_UNSPEC
also, xtables_strtoui() does the range check for us, no need for binary "&".
--- extensions/libxt_NFQUEUE.c | 20 +++----------------- 1 files changed, 3 insertions(+), 17 deletions(-)
extensions/libxt_NFQUEUE.c +3 -17
@@ -32,12 +32,12 @@ static void parse_num(const char *s, struct xt_NFQ_info *tinfo) { unsigned int num; - +if (!xtables_strtoui (s,NULL , &num,0 ,UINT16_MAX ))xtables_error (PARAMETER_PROBLEM ,"Invalid queue number `%s'\n" , s); - tinfo->queuenum = num &0xffff ; + tinfo->queuenum = num; } static int
@@ -78,7 +78,7 @@ static void NFQUEUE_save(const void *ip, const struct xt_entry_target *target) }static struct xtables_target nfqueue_target = { - .family =NFPROTO_IPV4 , + .family =NFPROTO_UNSPEC , .name ="NFQUEUE" , .version =XTABLES_VERSION , .size =XT_ALIGN (sizeof (struct xt_NFQ_info )),
@@ -90,21 +90,7 @@ static struct xtables_target nfqueue_target = { .extra_opts = NFQUEUE_opts }; -static struct xtables_target nfqueue_target6 = { - .family =NFPROTO_IPV6 , - .name ="NFQUEUE" , - .version =XTABLES_VERSION , - .size =XT_ALIGN (sizeof (struct xt_NFQ_info )), - .userspacesize =XT_ALIGN (sizeof (struct xt_NFQ_info )), - .help = NFQUEUE_help, - .parse = NFQUEUE_parse, - .print = NFQUEUE_print, - .save = NFQUEUE_save, - .extra_opts = NFQUEUE_opts, -}; -void _init (void ) {xtables_register_target (&nfqueue_target); -xtables_register_target (&nfqueue_target6); }
Signature · 1 line
1.6.0.6
Florian Westphal
maintainerPATCH 1/1 libxt_NFQUEUE: add new v1 version with queue-balance option
In reply to Florian WestphalNew version that adds support for specifying a queue range instead of a single queue id.
The kernel will distribute flows across the given queue range.
This is useful for multicore systems, simply 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 queue.
With fixes from Jan Engelhardt.
--- extensions/libxt_NFQUEUE.c | 109 +++++++++++++++++++++++++++++++++- extensions/libxt_NFQUEUE.man | 18 ++++-- include/linux/netfilter/xt_NFQUEUE.h | 5 ++ 3 files changed, 124 insertions(+), 8 deletions(-)
extensions/libxt_NFQUEUE.c +107 -2
@@ -23,19 +23,31 @@ static void NFQUEUE_help(void) ); } +static void NFQUEUE_help_v1 (void ) +{ +NFQUEUE_help (); +printf ( +" --queue-balance first:last Balance flows between queues <value> to <value>.\n" ); +} +static const struct option NFQUEUE_opts[] = { {"queue-num" ,1 ,NULL ,'F' }, + {"queue-balance" ,1 ,NULL ,'B' }, { .name =NULL } }; +static void exit_badqueue (const char *s) +{ +xtables_error (PARAMETER_PROBLEM ,"Invalid queue number `%s'\n" , s); +} +static void parse_num (const char *s,struct xt_NFQ_info *tinfo) {unsigned int num;if (!xtables_strtoui (s,NULL , &num,0 ,UINT16_MAX )) -xtables_error (PARAMETER_PROBLEM , -"Invalid queue number `%s'\n" , s); +exit_badqueue (s); tinfo->queuenum = num; }
@@ -54,6 +66,50 @@ NFQUEUE_parse(int c, char **argv, int invert, unsigned int *flags, "Only use --queue-num ONCE!");parse_num (optarg, tinfo);break ; +case 'B' : +xtables_error (PARAMETER_PROBLEM ,"NFQUEUE target: " +"--queue-balance not supported (kernel too old?)" ); +default : +return 0 ; + } + +return 1 ; +} + +static int +NFQUEUE_parse_v1 (int c,char **argv,int invert,unsigned int *flags, +const void *entry,struct xt_entry_target **target) +{ +struct xt_NFQ_info_v1 *info = (void *)(*target)->data; +char *colon; +unsigned int firstqueue, lastqueue; + +switch (c) { +case 'F' :/* fallthrough */ +case 'B' : +if (*flags) +xtables_error (PARAMETER_PROBLEM ,"NFQUEUE target: " +"Only use --queue-num ONCE!" ); + +if (!xtables_strtoui (optarg, &colon, &firstqueue,0 ,UINT16_MAX )) +exit_badqueue (optarg); + + info->queuenum = firstqueue; + +if (c =='F' ) +break ; + +if (*colon !=':' ) +xtables_error (PARAMETER_PROBLEM ,"Bad range \"%s\"" , optarg); + +if (!xtables_strtoui (colon +1 ,NULL , &lastqueue,1 ,UINT16_MAX )) +exit_badqueue (optarg); + +if (firstqueue >= lastqueue) +xtables_error (PARAMETER_PROBLEM ,"%u should be less than %u" , + firstqueue, lastqueue); + info->queues_total = lastqueue - firstqueue +1 ; +break ;default :return 0 ; }
@@ -69,6 +125,20 @@ static void NFQUEUE_print(const void *ip,printf ("NFQUEUE num %u" , tinfo->queuenum); } +static void NFQUEUE_print_v1 (const void *ip, +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; + +if (last >1 ) { + last += tinfo->queuenum -1 ; +printf ("NFQUEUE balance %u:%u" , tinfo->queuenum, last); + }else { +printf ("NFQUEUE num %u" , tinfo->queuenum); + } +} +static void NFQUEUE_save (const void *ip,const struct xt_entry_target *target) { const struct xt_NFQ_info *tinfo =
@@ -77,6 +147,25 @@ 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) +{ +const struct xt_NFQ_info_v1 *tinfo = (const void *)target->data; +unsigned int last = tinfo->queues_total; + +if (last >1 ) { + last += tinfo->queuenum -1 ; +printf ("--queue-balance %u:%u " , tinfo->queuenum, last); + }else { +printf ("--queue-num %u " , tinfo->queuenum); + } +} + +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 = { .family =NFPROTO_UNSPEC , .name ="NFQUEUE" ,
@@ -90,7 +179,23 @@ static struct xtables_target nfqueue_target = { .extra_opts = NFQUEUE_opts }; +static struct xtables_target nfqueue_target_v1 = { + .family =NFPROTO_UNSPEC , + .revision =1 , + .name ="NFQUEUE" , + .version =XTABLES_VERSION , + .size =XT_ALIGN (sizeof (struct xt_NFQ_info_v1 )), + .userspacesize =XT_ALIGN (sizeof (struct xt_NFQ_info_v1 )), + .help = NFQUEUE_help_v1, + .init = NFQUEUE_init_v1, + .parse = NFQUEUE_parse_v1, + .print = NFQUEUE_print_v1, + .save = NFQUEUE_save_v1, + .extra_opts = NFQUEUE_opts, +}; +void _init (void ) {xtables_register_target (&nfqueue_target); +xtables_register_target (&nfqueue_target_v1); }
extensions/libxt_NFQUEUE.man +12 -6
@@ -1,12 +1,18 @@ This target is an extension of the QUEUE target. As opposed to QUEUE, it allows you to put a packet into any specific queue, identified by its 16-bit queue -number. -.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. -.PP +number. It can only be used with Kernel versions 2.6.14 or later, since it requires the .B nfnetlink_queue -kernel support. +kernel support. The \fBqueue-balance\fP option was added in Linux 2.6.31. +.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. +.PP +.TP +\fB\-\-queue\-balance\fP \fIvalue\fP\fB:\fP\fIvalue\fP +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 \fIx\fP\fB:\fP\fIx+n\fP". +Packets belonging to the same connection are put into the same nfqueue.
include/linux/netfilter/xt_NFQUEUE.h +5 -0
@@ -13,4 +13,9 @@ struct xt_NFQ_info { u_int16_t queuenum; }; +struct xt_NFQ_info_v1 { +u_int16_t queuenum; +u_int16_t queues_total; +}; +#endif /* _XT_NFQ_TARGET_H */
Signature · 1 line
1.6.0.6
Re: [PATCH] libxt_NFQUEUE: add new v1 version with queue-balance option
Quoted 10 lines · Florian Westphal
New version that adds support for specifying a queue range instead of a single queue id.
The kernel will distribute flows across the given queue range.This is useful for multicore systems, simply 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 queue.With fixes from Jan Engelhardt.
This patch does not apply anymore, could you rediff against -git please? Thanks!
Florian Westphal
maintainerPATCH 1/1 libxt_NFQUEUE: add new v1 version with queue-balance option
New version that adds support for specifying a queue range instead of a single queue id.
The kernel will distribute flows across the given queue range.
This is useful for multicore systems, simply 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 queue.
With fixes from Jan Engelhardt.
---
changes since v1:
- bail out on --queue-num 1<something> (i.e. do not change behaviour, v1
did treat "--queue-num 1<something>" as "--queue-num 1")
extensions/libxt_NFQUEUE.c | 116 ++++++++++++++++++++++++++++++++- extensions/libxt_NFQUEUE.man | 18 ++++-- include/linux/netfilter/xt_NFQUEUE.h | 5 ++ 3 files changed, 129 insertions(+), 10 deletions(-)
extensions/libxt_NFQUEUE.c +112 -4
@@ -23,21 +23,33 @@ static void NFQUEUE_help(void) ); } +static void NFQUEUE_help_v1 (void ) +{ +NFQUEUE_help (); +printf ( +" --queue-balance first:last Balance flows between queues <value> to <value>.\n" ); +} +static const struct option NFQUEUE_opts[] = { {"queue-num" ,1 ,NULL ,'F' }, + {"queue-balance" ,1 ,NULL ,'B' }, { .name =NULL } }; +static void exit_badqueue (const char *s) +{ +xtables_error (PARAMETER_PROBLEM ,"Invalid queue number `%s'\n" , s); +} +static void parse_num (const char *s,struct xt_NFQ_info *tinfo) {unsigned int num; - +if (!xtables_strtoui (s,NULL , &num,0 ,UINT16_MAX )) -xtables_error (PARAMETER_PROBLEM , -"Invalid queue number `%s'\n" , s); +exit_badqueue (s); - tinfo->queuenum = num &0xffff ; + tinfo->queuenum = num; } static int
@@ -54,6 +66,53 @@ NFQUEUE_parse(int c, char **argv, int invert, unsigned int *flags, "Only use --queue-num ONCE!");parse_num (optarg, tinfo);break ; +case 'B' : +xtables_error (PARAMETER_PROBLEM ,"NFQUEUE target: " +"--queue-balance not supported (kernel too old?)" ); +default : +return 0 ; + } + +return 1 ; +} + +static int +NFQUEUE_parse_v1 (int c,char **argv,int invert,unsigned int *flags, +const void *entry,struct xt_entry_target **target) +{ +struct xt_NFQ_info_v1 *info = (void *)(*target)->data; +char *colon; +unsigned int firstqueue, lastqueue; + +switch (c) { +case 'F' :/* fallthrough */ +case 'B' : +if (*flags) +xtables_error (PARAMETER_PROBLEM ,"NFQUEUE target: " +"Only use --queue-num ONCE!" ); + +if (!xtables_strtoui (optarg, &colon, &firstqueue,0 ,UINT16_MAX )) +exit_badqueue (optarg); + + info->queuenum = firstqueue; + +if (c =='F' ) { +if (*colon) +exit_badqueue (optarg); +break ; + } + +if (*colon !=':' ) +xtables_error (PARAMETER_PROBLEM ,"Bad range \"%s\"" , optarg); + +if (!xtables_strtoui (colon +1 ,NULL , &lastqueue,1 ,UINT16_MAX )) +exit_badqueue (optarg); + +if (firstqueue >= lastqueue) +xtables_error (PARAMETER_PROBLEM ,"%u should be less than %u" , + firstqueue, lastqueue); + info->queues_total = lastqueue - firstqueue +1 ; +break ;default :return 0 ; }
@@ -69,6 +128,20 @@ static void NFQUEUE_print(const void *ip,printf ("NFQUEUE num %u" , tinfo->queuenum); } +static void NFQUEUE_print_v1 (const void *ip, +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; + +if (last >1 ) { + last += tinfo->queuenum -1 ; +printf ("NFQUEUE balance %u:%u" , tinfo->queuenum, last); + }else { +printf ("NFQUEUE num %u" , tinfo->queuenum); + } +} +static void NFQUEUE_save (const void *ip,const struct xt_entry_target *target) { const struct xt_NFQ_info *tinfo =
@@ -77,6 +150,25 @@ 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) +{ +const struct xt_NFQ_info_v1 *tinfo = (const void *)target->data; +unsigned int last = tinfo->queues_total; + +if (last >1 ) { + last += tinfo->queuenum -1 ; +printf ("--queue-balance %u:%u " , tinfo->queuenum, last); + }else { +printf ("--queue-num %u " , tinfo->queuenum); + } +} + +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 = { .family =NFPROTO_UNSPEC , .name ="NFQUEUE" ,
@@ -90,7 +182,23 @@ static struct xtables_target nfqueue_target = { .extra_opts = NFQUEUE_opts }; +static struct xtables_target nfqueue_target_v1 = { + .family =NFPROTO_UNSPEC , + .revision =1 , + .name ="NFQUEUE" , + .version =XTABLES_VERSION , + .size =XT_ALIGN (sizeof (struct xt_NFQ_info_v1 )), + .userspacesize =XT_ALIGN (sizeof (struct xt_NFQ_info_v1 )), + .help = NFQUEUE_help_v1, + .init = NFQUEUE_init_v1, + .parse = NFQUEUE_parse_v1, + .print = NFQUEUE_print_v1, + .save = NFQUEUE_save_v1, + .extra_opts = NFQUEUE_opts, +}; +void _init (void ) {xtables_register_target (&nfqueue_target); +xtables_register_target (&nfqueue_target_v1); }
extensions/libxt_NFQUEUE.man +12 -6
@@ -1,12 +1,18 @@ This target is an extension of the QUEUE target. As opposed to QUEUE, it allows you to put a packet into any specific queue, identified by its 16-bit queue -number. -.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. -.PP +number. It can only be used with Kernel versions 2.6.14 or later, since it requires the .B nfnetlink_queue -kernel support. +kernel support. The \fBqueue-balance\fP option was added in Linux 2.6.31. +.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. +.PP +.TP +\fB\-\-queue\-balance\fP \fIvalue\fP\fB:\fP\fIvalue\fP +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 \fIx\fP\fB:\fP\fIx+n\fP". +Packets belonging to the same connection are put into the same nfqueue.
include/linux/netfilter/xt_NFQUEUE.h +5 -0
@@ -13,4 +13,9 @@ struct xt_NFQ_info { u_int16_t queuenum; }; +struct xt_NFQ_info_v1 { +u_int16_t queuenum; +u_int16_t queues_total; +}; +#endif /* _XT_NFQ_TARGET_H */
Signature · 1 line
1.6.3.3
Re: [PATCH] libxt_NFQUEUE: add new v1 version with queue-balance option
Quoted 15 lines · Florian Westphal
New version that adds support for specifying a queue range instead of a single queue id.
The kernel will distribute flows across the given queue range.This is useful for multicore systems, simply 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 queue.With fixes from Jan Engelhardt.
Signed-off-by Florian Westphal <[email protected]>---
changes since v1:
- bail out on --queue-num 1<something> (i.e. do not change behaviour, v1
Quoted 6 lines
did treat "--queue-num 1<something>" as "--queue-num 1")extensions/libxt_NFQUEUE.c | 116 ++++++++++++++++++++++++++++++++- extensions/libxt_NFQUEUE.man | 18 ++++-- include/linux/netfilter/xt_NFQUEUE.h | 5 ++ 3 files changed, 129 insertions(+), 10 deletions(-)
Applied and pushed out, thanks Florian.