From eea9882953efd550b3a16270888131dcf7deb881 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Fri, 9 Dec 2016 10:46:39 -0800 Subject: [PATCH] Implement CPU Fanout for NFQUEUE. Signed-off-by: Tom Eastep --- Shorewall-core/lib.cli | 12 ++++++++++-- Shorewall/Perl/Shorewall/Config.pm | 10 +++++++++- Shorewall/Perl/Shorewall/Rules.pm | 6 ++++-- Shorewall/manpages/shorewall-rules.xml | 11 +++++++++-- Shorewall6/manpages/shorewall6-rules.xml | 13 ++++++++++--- 5 files changed, 42 insertions(+), 10 deletions(-) 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).