diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm
index 5cf6314d7..bd1779d61 100644
--- a/Shorewall/Perl/Shorewall/Chains.pm
+++ b/Shorewall/Perl/Shorewall/Chains.pm
@@ -806,7 +806,7 @@ sub transform_rule( $ ) {
}
}
- set_rule_option( $ruleref, $option, $params ) unless $params eq '';
+ set_rule_option( $ruleref, $option, $params );
}
$ruleref->{simple} = $simple;
diff --git a/Shorewall/Perl/Shorewall/Tc.pm b/Shorewall/Perl/Shorewall/Tc.pm
index d50b57b84..6b655219c 100644
--- a/Shorewall/Perl/Shorewall/Tc.pm
+++ b/Shorewall/Perl/Shorewall/Tc.pm
@@ -169,6 +169,7 @@ my %restrictions = ( tcpre => PREROUTE_RESTRICT ,
tcout => OUTPUT_RESTRICT );
my $family;
+my $divert;
#
# Rather than initializing globals in an INIT block or during declaration,
@@ -191,6 +192,7 @@ sub initialize( $ ) {
$devnum = 0;
$sticky = 0;
$ipp2p = 0;
+ $divert = 0;
}
sub process_tc_rule( ) {
@@ -242,6 +244,7 @@ sub process_tc_rule( ) {
my $restriction = 0;
my $cmd;
my $rest;
+ my $matches = '';
my %processtcc = ( sticky => sub() {
if ( $chain eq 'tcout' ) {
@@ -294,6 +297,32 @@ sub process_tc_rule( ) {
$target = "IPMARK --addr $srcdst --and-mask $mask1 --or-mask $mask2 --shift $shift";
},
+ DIVERT => sub() {
+ fatal_error "Invalid DIVERT specification( $cmd/$rest )" if $rest;
+
+ $chain = 'tcpre';
+
+ $cmd =~ /DIVERT\((.+?)\)$/;
+
+ $mark = $1;
+
+ fatal_error "Invalid DIVERT specification( $cmd )" unless defined $mark;
+
+ my $val = numeric_value( $mark );
+
+ validate_mark $val . '/' . in_hex( $globals{PROVIDER_MASK} );
+
+ my $divertref = new_chain( 'mangle', 'DIVERT' . ( $divert ? $divert : '' ) );
+
+ $divert++;
+
+ add_ijump( $divertref , j => 'MARK', targetopts => '--set-mark ' . in_hex( $val ) . '/' . in_hex( $globals{PROVIDER_MASK} ) );
+ add_ijump( $divertref , j => 'ACCEPT' );
+
+ $target = $divertref->{name};
+
+ $matches = '-m socket ';
+ },
TPROXY => sub() {
require_capability( 'TPROXY_TARGET', 'Use of TPROXY', 's');
@@ -539,7 +568,8 @@ sub process_tc_rule( ) {
do_helper( $helper ) .
do_headers( $headers ) .
do_probability( $probability ) .
- do_dscp( $dscp ),
+ do_dscp( $dscp ) .
+ $matches ,
$source ,
$dest ,
'' ,
@@ -2002,6 +2032,11 @@ sub setup_tc() {
mark => HIGHMARK,
mask => '',
connmark => '' },
+ { match => sub( $ ) { $_[0] =~ /^DIVERT/ },
+ target => 'DIVERT',
+ mark => HIGHMARK,
+ mask => '',
+ connmark => '' },
{ match => sub( $ ) { $_[0] =~ /^TTL/ },
target => 'TTL',
mark => NOMARK,
diff --git a/Shorewall/manpages/shorewall-tcrules.xml b/Shorewall/manpages/shorewall-tcrules.xml
index 118634c5e..e0293b90a 100644
--- a/Shorewall/manpages/shorewall-tcrules.xml
+++ b/Shorewall/manpages/shorewall-tcrules.xml
@@ -407,6 +407,19 @@ SAME $FW 0.0.0.0/0 tcp 80,443
classes will have a value > 256.
+
+ DIVERT(mark)
+
+ Added in Shorewall 4.5.3. A DIVERT rule should preceed
+ each TPROXY rule and should specify the same
+ mark value. DIVERT avoids sending
+ packets to the TPROXY target once a socket connection to Squid3
+ has been established by TPROXY. DIVERT marks the packet with the
+ specified mark and exempts it from
+ any rules that follow.
+
+
TPROXY(mark[/mask][,[port][,[address]]])
@@ -438,6 +451,12 @@ SAME $FW 0.0.0.0/0 tcp 80,443
request arrives.
+
+
+ A DIVERT rule specifying the same
+ mark value and other column values
+ should preceed each TPROXY rule.
+
diff --git a/Shorewall6/manpages/shorewall6-tcrules.xml b/Shorewall6/manpages/shorewall6-tcrules.xml
index 103653f78..ebe7fc79c 100644
--- a/Shorewall6/manpages/shorewall6-tcrules.xml
+++ b/Shorewall6/manpages/shorewall6-tcrules.xml
@@ -304,6 +304,19 @@ SAME $FW 0.0.0.0/0 tcp 80,443
simply include COMMENT on a line by itself.
+
+ DIVERT(mark)
+
+ Added in Shorewall 4.5.3. A DIVERT rule should preceed
+ each TPROXY rule and should specify the same
+ mark value. DIVERT avoids sending
+ packets to the TPROXY target once a socket connection to Squid3
+ has been established by TPROXY. DIVERT marks the packet with the
+ specified mark and exempts it from
+ any rules that follow.
+
+
TPROXY(mark[/mask][,[port][,[address]]])
@@ -335,6 +348,12 @@ SAME $FW 0.0.0.0/0 tcp 80,443
request arrives.
+
+
+ A DIVERT rule specifying the same
+ mark value and other column values
+ should preceed each TPROXY rule.
+
diff --git a/docs/Shorewall_Squid_Usage.xml b/docs/Shorewall_Squid_Usage.xml
index af678e68e..92e6f8851 100644
--- a/docs/Shorewall_Squid_Usage.xml
+++ b/docs/Shorewall_Squid_Usage.xml
@@ -336,8 +336,16 @@ Tproxy 1 1 - lo - local
MARK SOURCE DEST PROTO PORT(S)
+DIVERT(1) eth1 0.0.0.0/0 tcp 80
TPROXY(1,3128) eth1 0.0.0.0/0 tcp 80
+
+ The DIVERT action was added in Shorewall 4.5.3; user's running
+ earlier versions of Shorewall will need to use the start extension script to add the
+ DIVERT logic mentioned in the Squid article linked above.
+
+
/etc/shorewall/rules:
#ACTION SOURCE DEST PROTO DEST PORT(S)