diff --git a/Shorewall/Perl/Shorewall/Providers.pm b/Shorewall/Perl/Shorewall/Providers.pm index 6ed0d1cdd..69d8892f9 100644 --- a/Shorewall/Perl/Shorewall/Providers.pm +++ b/Shorewall/Perl/Shorewall/Providers.pm @@ -40,11 +40,12 @@ our @EXPORT = qw( process_providers handle_stickiness handle_optional_interfaces ); our @EXPORT_OK = qw( initialize lookup_provider ); -our $VERSION = 'MODULEVERSION'; +our $VERSION = '4.4_24'; use constant { LOCAL_TABLE => 255, MAIN_TABLE => 254, DEFAULT_TABLE => 253, + BALANCE_TABLE => 250, UNSPEC_TABLE => 0 }; @@ -93,6 +94,7 @@ sub initialize( $ ) { %providers = ( local => { number => LOCAL_TABLE , mark => 0 , optional => 0 ,routes => [], rules => [] } , main => { number => MAIN_TABLE , mark => 0 , optional => 0 ,routes => [], rules => [] } , default => { number => DEFAULT_TABLE , mark => 0 , optional => 0 ,routes => [], rules => [] } , + balance => { number => BALANCE_TABLE , mark => 0 , optional => 0 ,routes => [], rules => [] } , unspec => { number => UNSPEC_TABLE , mark => 0 , optional => 0 ,routes => [], rules => [] } ); @providers = (); } @@ -347,23 +349,17 @@ sub process_a_provider() { $mtu = "mtu $1 "; } elsif ( $option =~ /^fallback=(\d+)$/ ) { fatal_error q('fallback' is not available in IPv6) if $family == F_IPV6; - if ( $config{USE_DEFAULT_RT} ) { - warning_message "'fallback' is ignored when USE_DEFAULT_RT=Yes"; - } else { - $default = $1; - fatal_error 'fallback must be non-zero' unless $default; - } + $default = $1; + $default_balance = 0; + fatal_error 'fallback must be non-zero' unless $default; } elsif ( $option eq 'fallback' ) { fatal_error q('fallback' is not available in IPv6) if $family == F_IPV6; - if ( $config{USE_DEFAULT_RT} ) { - warning_message "'fallback' is ignored when USE_DEFAULT_RT=Yes"; - } else { - $default = -1; - } + $default = -1; + $default_balance = 0; } elsif ( $option eq 'local' ) { $local = 1; $track = 0 if $config{TRACK_PROVIDERS}; - $default_balance = 0 if$config{USE_DEFAULT_RT}; + $default_balance = 0 if $config{USE_DEFAULT_RT}; } else { fatal_error "Invalid option ($option)"; } @@ -559,18 +555,19 @@ sub add_a_provider( $$ ) { emit "qt \$IP -6 route del $gateway src $address dev $physical ${mtu}table $number $realm"; emit "run_ip route add $gateway src $address dev $physical ${mtu}table $number $realm"; } - + emit "run_ip route add default via $gateway src $address dev $physical ${mtu}table $number $realm"; } - balance_default_route( $balance , $gateway, $physical, $realm ) if $balance; - - if ( $default > 0 ) { + if ( $balance ) { + balance_default_route( $balance , $gateway, $physical, $realm ); + } elsif ( $default > 0 ) { balance_fallback_route( $default , $gateway, $physical, $realm ); } elsif ( $default ) { emit ''; if ( $gateway ) { if ( $family == F_IPV4 ) { + emit qq(run_ip route replace $gateway dev $physical table ) . DEFAULT_TABLE; emit qq(run_ip route replace default via $gateway src $address dev $physical table ) . DEFAULT_TABLE . qq( metric $number); } else { emit qq(qt \$IP -6 route del default via $gateway src $address dev $physical table ) . DEFAULT_TABLE . qq( metric $number); @@ -581,8 +578,8 @@ sub add_a_provider( $$ ) { emit qq(run_ip route add default table ) . DEFAULT_TABLE . qq( dev $physical metric $number); emit qq(echo "qt \$IP -$family route del default dev $physical table ) . DEFAULT_TABLE . qq(" >> \${VARDIR}/undo_${table}_routing); } - - $default = 1; + + $fallback = 1; } unless ( $local ) { @@ -631,8 +628,8 @@ sub add_a_provider( $$ ) { push_indent; - if ( $balance || $default ) { - $tbl = $default || $config{USE_DEFAULT_RT} ? DEFAULT_TABLE : MAIN_TABLE; + if ( $balance || $default > 0 ) { + $tbl = $default ? DEFAULT_TABLE : $config{USE_DEFAULT_RT} ? BALANCE_TABLE : MAIN_TABLE; $weight = $balance ? $balance : $default; if ( $gateway ) { @@ -699,30 +696,40 @@ sub add_a_provider( $$ ) { my $undo = "\${VARDIR}/undo_${table}_routing"; - emit( "if [ -f $undo ]; then", - " . $undo", - " > $undo" ); + emit( "if [ -f $undo ]; then" ); - if ( $balance || $default ) { - $tbl = $fallback || ( $config{USE_DEFAULT_RT} ? DEFAULT_TABLE : MAIN_TABLE ); + push_indent; + + if ( $balance || $default > 0 ) { + $tbl = $default ? DEFAULT_TABLE : $config{USE_DEFAULT_RT} ? BALANCE_TABLE : MAIN_TABLE; $weight = $balance ? $balance : $default; - my $via = 'via'; + my $via; - $via .= " $gateway" if $gateway; - $via .= " dev $physical"; - $via .= " weight $weight"; + if ( $gateway ) { + $via = "via $gateway dev $physical"; + } else { + $via = "dev $physical"; + } + + $via .= " weight $weight" unless $weight < 0; $via .= " $realm" if $realm; - emit( qq( delete_gateway "$via" $tbl $physical) ); + emit( qq(delete_gateway "$via" $tbl $physical) ); } - - emit( '', - " qt \$TC qdisc del dev $physical root", - " qt \$TC qdisc del dev $physical ingress\n" ) if $tcdevices->{$interface}; - emit( " progress_message2 \"Provider $table stopped\"", - 'else', + emit (". $undo", + "> $undo" ); + + emit( '', + "qt \$TC qdisc del dev $physical root", + "qt \$TC qdisc del dev $physical ingress\n" ) if $tcdevices->{$interface}; + + emit( "progress_message2 \"Provider $table stopped\"" ); + + pop_indent; + + emit( 'else', " startup_error \"$undo does not exist\"", 'fi' ); @@ -916,12 +923,14 @@ sub finish_providers() { my $table = MAIN_TABLE; if ( $config{USE_DEFAULT_RT} ) { - emit ( 'run_ip rule add from ' . ALLIP . ' table ' . MAIN_TABLE . ' pref 999', + emit ( 'run_ip rule add from ' . ALLIP . ' table ' . MAIN_TABLE . ' pref 999', + 'run_ip rule add from ' . ALLIP . ' table ' . BALANCE_TABLE . ' pref 32765', "\$IP -$family rule del from " . ALLIP . ' table ' . MAIN_TABLE . ' pref 32766', - qq(echo "qt \$IP -$family rule add from ) . ALLIP . ' table ' . MAIN_TABLE . ' pref 32766" >> ${VARDIR}/undo_main_routing', - qq(echo "qt \$IP -$family rule del from ) . ALLIP . ' table ' . MAIN_TABLE . ' pref 999" >> ${VARDIR}/undo_main_routing', + qq(echo "qt \$IP -$family rule add from ) . ALLIP . ' table ' . MAIN_TABLE . ' pref 32766" >> ${VARDIR}/undo_main_routing', + qq(echo "qt \$IP -$family rule del from ) . ALLIP . ' table ' . MAIN_TABLE . ' pref 999" >> ${VARDIR}/undo_main_routing', + qq(echo "qt \$IP -$family rule del from ) . ALLIP . ' table ' . BALANCE_TABLE . ' pref 32765" >> ${VARDIR}/undo_balance_routing', '' ); - $table = DEFAULT_TABLE; + $table = BALANCE_TABLE; } emit ( 'if [ -n "$DEFAULT_ROUTE" ]; then' ); @@ -972,6 +981,8 @@ sub finish_providers() { emit( " progress_message \"Fallback route '\$(echo \$FALLBACK_ROUTE | sed 's/\$\\s*//')' Added\"", 'fi', '' ); + } elsif ( $config{USE_DEFAULT_RT} ) { + emit "qt \$IP -$family route del default table " . DEFAULT_TABLE; } unless ( $config{KEEP_RT_TABLES} ) { @@ -984,7 +995,7 @@ sub finish_providers() { '#', LOCAL_TABLE . "\tlocal", MAIN_TABLE . "\tmain", - DEFAULT_TABLE . "\tdefault", + $config{USE_DEFAULT_RT} ? ( DEFAULT_TABLE . "\tdefault\n" . BALANCE_TABLE . "\tbalance" ) : DEFAULT_TABLE . "\tdefault", "0\tunspec", '#', '# local', diff --git a/docs/MultiISP.xml b/docs/MultiISP.xml index 86bf3f2e8..5bd842eeb 100644 --- a/docs/MultiISP.xml +++ b/docs/MultiISP.xml @@ -535,8 +535,10 @@ is given without a weight, a separate default route is added through the provider's gateway; the route has a metric equal to the provider's - NUMBER. The option is ignored with a warning message if - USE_DEFAULT_RT=Yes in + NUMBER. + + Prior to Shorewall 4.4.24, the option is ignored with + a warning message if USE_DEFAULT_RT=Yes in shorewall.conf. diff --git a/manpages/shorewall-providers.xml b/manpages/shorewall-providers.xml index d9238fc12..d2fb1fdcb 100644 --- a/manpages/shorewall-providers.xml +++ b/manpages/shorewall-providers.xml @@ -263,8 +263,10 @@ specified weight. If the option is given without a weight, an separate default route is added through the provider's gateway; the - route has a metric equal to the provider's NUMBER. The option - is ignored with a warning message if USE_DEFAULT_RT=Yes in + route has a metric equal to the provider's NUMBER. + + Prior to Shorewall 4.4.24, the option is ignored with a + warning message if USE_DEFAULT_RT=Yes in shorewall.conf.