diff --git a/Shorewall-core/lib.cli b/Shorewall-core/lib.cli
index d50257bff..a35fdfc79 100644
--- a/Shorewall-core/lib.cli
+++ b/Shorewall-core/lib.cli
@@ -25,7 +25,7 @@
# loaded after this one and replaces some of the functions declared here.
#
-SHOREWALL_CAPVERSION=50004
+SHOREWALL_CAPVERSION=50100
if [ -z "$g_basedir" ]; then
#
@@ -2799,6 +2799,7 @@ determine_capabilities() {
IFACE_MATCH=
TCPMSS_TARGET=
WAIT_OPTION=
+ CPU_FANOUT=
AMANDA_HELPER=
FTP_HELPER=
@@ -3096,7 +3097,12 @@ determine_capabilities() {
qt $g_tool -A $chain -m hashlimit --hashlimit 4 --hashlimit-burst 5 --hashlimit-name $chain --hashlimit-mode dstip -j ACCEPT && OLD_HL_MATCH=Yes
HASHLIMIT_MATCH=$OLD_HL_MATCH
fi
- qt $g_tool -A $chain -j NFQUEUE --queue-num 4 && NFQUEUE_TARGET=Yes
+
+ if qt $g_tool -A $chain -j NFQUEUE --queue-num 4; then
+ NFQUEUE_TARGET=Yes
+ qt $g_tool -A $chain -j NFQUEUE --queue-balance 0:3 --queue-cpu-fanout && CPU_FANOUT=Yes
+ fi
+
qt $g_tool -A $chain -m realm --realm 4 && REALM_MATCH=Yes
#
@@ -3294,6 +3300,7 @@ report_capabilities_unsorted() {
report_capability "Basic Filter (BASIC_FILTER)" $BASIC_FILTER
report_capability "Basic Ematch (BASIC_EMATCH)" $BASIC_EMATCH
report_capability "CT Target (CT_TARGET)" $CT_TARGET
+ report_capability "NFQUEUE CPU Fanout (CPU_FANOUT)" $CPU_FANOUT
echo " Kernel Version (KERNELVERSION): $KERNELVERSION"
echo " Capabilities Version (CAPVERSION): $CAPVERSION"
@@ -3399,6 +3406,7 @@ report_capabilities_unsorted1() {
report_capability1 IFACE_MATCH
report_capability1 TCPMSS_TARGET
report_capability1 WAIT_OPTION
+ report_capability1 CPU_FANOUT
report_capability1 AMANDA_HELPER
report_capability1 FTP_HELPER
diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm
index 632de9651..2202f384e 100644
--- a/Shorewall/Perl/Shorewall/Config.pm
+++ b/Shorewall/Perl/Shorewall/Config.pm
@@ -412,6 +412,7 @@ our %capdesc = ( NAT_ENABLED => 'NAT',
IFACE_MATCH => 'Iface Match',
TCPMSS_TARGET => 'TCPMSS Target',
WAIT_OPTION => 'iptables --wait option',
+ CPU_FANOUT => 'NFQUEUE CPU Fanout',
AMANDA_HELPER => 'Amanda Helper',
FTP_HELPER => 'FTP Helper',
@@ -748,7 +749,7 @@ sub initialize( $;$$) {
EXPORT => 0,
KLUDGEFREE => '',
VERSION => "5.0.9-Beta2",
- CAPVERSION => 50004 ,
+ CAPVERSION => 50100 ,
BLACKLIST_LOG_TAG => '',
RELATED_LOG_TAG => '',
MACLIST_LOG_TAG => '',
@@ -1035,6 +1036,7 @@ sub initialize( $;$$) {
IFACE_MATCH => undef,
TCPMSS_TARGET => undef,
WAIT_OPTION => undef,
+ CPU_FANOUT => undef,
AMANDA_HELPER => undef,
FTP_HELPER => undef,
@@ -4845,6 +4847,10 @@ sub Tcpmss_Target() {
qt1( "$iptables $iptablesw -A $sillyname -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu" );
}
+sub Cpu_Fanout() {
+ have_capability( 'NFQUEUE_TARGET' ) && qt1( "$iptables -A $sillyname -j NFQUEUE --queue-balance 0:3 --queue-cpu-fanout" );
+}
+
our %detect_capability =
( ACCOUNT_TARGET =>\&Account_Target,
AMANDA_HELPER => \&Amanda_Helper,
@@ -4861,6 +4867,7 @@ our %detect_capability =
CONNMARK => \&Connmark,
CONNMARK_MATCH => \&Connmark_Match,
CONNTRACK_MATCH => \&Conntrack_Match,
+ CPU_FANOUT => \&Cpu_Fanout,
CT_TARGET => \&Ct_Target,
DSCP_MATCH => \&Dscp_Match,
DSCP_TARGET => \&Dscp_Target,
@@ -5088,6 +5095,7 @@ sub determine_capabilities() {
$capabilities{TARPIT_TARGET} = detect_capability( 'TARPIT_TARGET' );
$capabilities{IFACE_MATCH} = detect_capability( 'IFACE_MATCH' );
$capabilities{TCPMSS_TARGET} = detect_capability( 'TCPMSS_TARGET' );
+ $capabilities{CPU_FANOUT} = detect_capability( 'CPU_FANOUT' );
unless ( have_capability 'CT_TARGET' ) {
$capabilities{HELPER_MATCH} = detect_capability 'HELPER_MATCH';
diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm
index 107439c42..9c1179363 100644
--- a/Shorewall/Perl/Shorewall/Rules.pm
+++ b/Shorewall/Perl/Shorewall/Rules.pm
@@ -574,7 +574,7 @@ sub process_default_action( $$$$ ) {
#
sub handle_nfqueue( $$ ) {
my ($params, $allow_bypass ) = @_;
- my ( $action, $bypass );
+ my ( $action, $bypass, $fanout );
my ( $queue1, $queue2, $queuenum1, $queuenum2 );
require_capability( 'NFQUEUE_TARGET', 'NFQUEUE Rules and Policies', '' );
@@ -600,6 +600,7 @@ sub handle_nfqueue( $$ ) {
fatal_error "Invalid NFQUEUE queue number ($queue1)" unless defined( $queuenum1) && $queuenum1 >= 0 && $queuenum1 <= 65535;
if ( supplied $queue2 ) {
+ $fanout = ' --queue-cpu-fanout' if $queue2 =~ s/c$//;
$queuenum2 = numeric_value( $queue2 );
fatal_error "Invalid NFQUEUE queue number ($queue2)" unless defined( $queuenum2) && $queuenum2 >= 0 && $queuenum2 <= 65535 && $queuenum1 < $queuenum2;
@@ -621,7 +622,8 @@ sub handle_nfqueue( $$ ) {
}
if ( supplied $queue2 ) {
- return "NFQUEUE --queue-balance ${queuenum1}:${queuenum2}${bypass}";
+ require_capability 'CPU_FANOUT', '"c"', 's' if $fanout;
+ return "NFQUEUE --queue-balance ${queuenum1}:${queuenum2}${fanout}${bypass}";
} else {
return "NFQUEUE --queue-num ${queuenum1}${bypass}";
}
diff --git a/Shorewall/manpages/shorewall-rules.xml b/Shorewall/manpages/shorewall-rules.xml
index 4df32e2f9..dcd746ae8 100644
--- a/Shorewall/manpages/shorewall-rules.xml
+++ b/Shorewall/manpages/shorewall-rules.xml
@@ -629,7 +629,7 @@
NFQUEUE[([queuenumber1[:queuenumber2][,bypass]]|bypass)]
+ role="bold">NFQUEUE[([queuenumber1[:queuenumber2[c]][,bypass]]|bypass)]
Queues the packet to a user-space application using the
@@ -648,12 +648,19 @@
systems: start multiple instances of the userspace program on
queues x, x+1, .. x+n and use "x:x+n". Packets belonging to
the same connection are put into the same nfqueue.
+
+ Beginning with Shorewall 5.1.0, queuenumber2 may be
+ followed by the letter 'c' to indicate that the CPU ID will be
+ used as an index to map packets to the queues. The idea is
+ that you can improve performance if there's a queue per CPU.
+ Requires the NFQUEUE CPU Fanout capability in your kernel and
+ iptables.
NFQUEUE![([queuenumber1[,queuenumber2][,bypass]]|bypass)]
+ role="bold">NFQUEUE![([queuenumber1[:queuenumber2[c]][,bypass]]|bypass)]
like NFQUEUE but exempts the rule from being suppressed
diff --git a/Shorewall6/manpages/shorewall6-rules.xml b/Shorewall6/manpages/shorewall6-rules.xml
index 32b64db4f..a64bed445 100644
--- a/Shorewall6/manpages/shorewall6-rules.xml
+++ b/Shorewall6/manpages/shorewall6-rules.xml
@@ -606,7 +606,7 @@
NFQUEUE[([queuenumber1[:queuenumber2][,bypass]]|bypass)]
+ role="bold">NFQUEUE[([queuenumber1[:queuenumber2[c]][,bypass]]|bypass)]
Queues the packet to a user-space application using the
@@ -625,17 +625,24 @@
systems: start multiple instances of the userspace program on
queues x, x+1, .. x+n and use "x:x+n". Packets belonging to
the same connection are put into the same nfqueue.
+
+ Beginning with Shorewall 5.1.0, queuenumber2 may be
+ followed by the letter 'c' to indicate that the CPU ID will be
+ used as an index to map packets to the queues. The idea is
+ that you can improve performance if there's a queue per CPU.
+ Requires the NFQUEUE CPU Fanout capability in your kernel and
+ iptables.
NFQUEUE![([queuenumber1[,queuenumber2][,bypass]]|bypass)]
+ role="bold">NFQUEUE![([queuenumber1[:queuenumber2[c]][,bypass]]|bypass)]
like NFQUEUE but exempts the rule from being suppressed
by OPTIMIZE=1 in shorewall6.conf(5).
+ url="shorewall6.conf.html">shorewall6.conf(5).