From 9f002acb201ca71450a42ce2d9020390ed6aabd5 Mon Sep 17 00:00:00 2001 From: teastep Date: Thu, 15 Mar 2007 01:38:04 +0000 Subject: [PATCH] Add Providers Module git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@5537 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb --- New/Shorewall/Providers.pm | 420 +++++++++++++++++++++++++++++++++++++ New/Shorewall/Tc.pm | 6 +- New/compiler.pl | 407 +---------------------------------- 3 files changed, 426 insertions(+), 407 deletions(-) create mode 100644 New/Shorewall/Providers.pm diff --git a/New/Shorewall/Providers.pm b/New/Shorewall/Providers.pm new file mode 100644 index 000000000..463408c07 --- /dev/null +++ b/New/Shorewall/Providers.pm @@ -0,0 +1,420 @@ +package Shorewall::Providers; +require Exporter; +use Shorewall::Common; +use Shorewall::Config; +use Shorewall::Zones; +use Shorewall::Chains; + +use strict; + +our @ISA = qw(Exporter); +our @EXPORT = qw( setup_providers ); +our @EXPORT_OK = ( ); +our @VERSION = 1.00; + +use constant { LOCAL_NUMBER => 255, + MAIN_NUMBER => 254, + DEFAULT_NUMBER => 253, + UNSPEC_NUMBER => 0 + }; + +my $balance = 0; +my $first_default_route = 1; + + +my %providers = ( 'local' => { number => LOCAL_NUMBER , mark => 0 } , + main => { number => MAIN_NUMBER , mark => 0 } , + default => { number => DEFAULT_NUMBER , mark => 0 } , + unspec => { number => UNSPEC_NUMBER , mark => 0 } ); + +my @providers; +my %routemarked_interfaces; +my $routemarked_interfaces = 0; + +# +# Set up marking for 'tracked' interfaces. Unline in Shorewall 3.x, we add these rules inconditionally, even if the associated interface isn't up. +# +sub setup_route_marking() { + my $mask = $config{HIGH_ROUTE_MARKS} ? '0xFFFF' : '0xFF'; + my $mark_op = $config{HIGH_ROUTE_MARKS} ? '--or-mark' : '--set-mark'; + + add_rule $mangle_table->{PREROUTING} , "-m connmark ! --mark 0/$mask -j CONNMARK --restore-mark --mask $mask"; + add_rule $mangle_table->{OUTPUT} , " -m connmark ! --mark 0/$mask -j CONNMARK --restore-mark --mask $mask"; + + my $chainref = new_chain 'mangle', 'routemark'; + + while ( my ( $interface, $mark ) = ( each %routemarked_interfaces ) ) { + add_rule $mangle_table->{PREROUTING} , "-i $interface -m mark --mark 0/$mask -j routemark"; + add_rule $chainref, " -i $interface -j MARK $mark_op $mark"; + } + + add_rule $chainref, "-m mark ! --mark 0/$mask -j CONNMARK --save-mark --mask $mask"; +} + +sub setup_providers() { + my $fn = find_file 'providers'; + my $providers = 0; + + sub copy_table( $$ ) { + my ( $duplicate, $number ) = @_; + + emit "ip route show table $duplicate | while read net route; do"; + emit ' case $net in'; + emit ' default|nexthop)'; + emit ' ;;'; + emit ' *)'; + emit " run_ip route add table $number \$net \$route"; + emit ' ;;'; + emit ' esac'; + emit "done\n"; + } + + sub copy_and_edit_table( $$$ ) { + my ( $duplicate, $number, $copy ) = @_; + + my $match = $copy; + + $match =~ s/ /\|/g; + + emit "ip route show table $duplicate | while read net route; do"; + emit ' case $net in'; + emit ' default|nexthop)'; + emit ' ;;'; + emit ' *)'; + emit " run_ip route add table $number \$net \$route"; + emit ' case $(find_device $route) in'; + emit " $match)"; + emit " run_ip route add table $number \$net \$route"; + emit ' ;;'; + emit ' esac'; + emit ' ;;'; + emit ' esac'; + emit "done\n"; + } + + sub balance_default_route( $$$ ) { + my ( $weight, $gateway, $interface ) = @_; + + $balance = 1; + + emit ''; + + if ( $first_default_route ) { + if ( $gateway ) { + emit "DEFAULT_ROUTE=\"nexthop via $gateway dev $interface weight $weight\""; + } else { + emit "DEFAULT_ROUTE=\"nexthop dev $interface weight $weight\""; + } + + $first_default_route = 0; + } else { + if ( $gateway ) { + emit "DEFAULT_ROUTE=\"\$DEFAULT_ROUTE nexthop via $gateway dev $interface weight $weight\""; + } else { + emit "DEFAULT_ROUTE=\"\$DEFAULT_ROUTE nexthop dev $interface weight $weight\""; + } + } + } + + sub add_a_provider( $$$$$$$$ ) { + + my ($table, $number, $mark, $duplicate, $interface, $gateway, $options, $copy) = @_; + + fatal_error 'Providers require mangle support in your kernel and iptables' unless $capabilities{MANGLE_ENABLED}; + + fatal_error "Duplicate provider ( $table )" if $providers{$table}; + + for my $provider ( keys %providers ) { + fatal_error "Duplicate provider number ( $number )" if $providers{$provider}{number} == $number; + } + + emit "#\n# Add Provider $table ($number)\n#"; + + emit "if interface_is_usable $interface; then"; + push_indent; + my $iface = chain_base $interface; + + emit "${iface}_up=Yes"; + emit "qt ip route flush table $number"; + emit "echo \"qt ip route flush table $number\" >> \${VARDIR}/undo_routing"; + + $duplicate = '-' unless $duplicate; + $copy = '-' unless $copy; + + if ( $duplicate ne '-' ) { + if ( $copy ne '-' ) { + if ( $copy eq 'none' ) { + $copy = $interface; + } else { + my @c = ( split /,/, $copy ); + $copy = "@c"; + } + + copy_and_edit_table( $duplicate, $number ,$copy ); + } else { + copy_table ( $duplicate, $number ); + } + } else { + fatal_error 'A non-empty COPY column requires that a routing table be specified in the DUPLICATE column' if $copy ne '-'; + } + + $gateway = '-' unless $gateway; + + if ( $gateway eq 'detect' ) { + emit "gateway=\$(detect_gateway $interface)\n"; + + emit 'if [ -n "$gateway" ]; then'; + emit " run_ip route replace \$gateway src \$(find_first_interface_address $interface) dev $interface table $number"; + emit " run_ip route add default via \$gateway dev $interface table $number"; + emit 'else'; + emit " fatal_error \"Unable to detect the gateway through interface $interface\""; + emit "fi\n"; + } elsif ( $gateway && $gateway ne '-' ) { + emit "run_ip route replace $gateway src \$(find_first_interface_address $interface) dev $interface table $number"; + emit "run_ip route add default via $gateway dev $interface table $number"; + } else { + $gateway = ''; + emit "run_ip route add default dev $interface table $number"; + } + + $mark = '-' unless $mark; + + my $val = 0; + + if ( $mark ne '-' ) { + + $val = numeric_value $mark; + + verify_mark $mark; + + if ( $val < 256) { + fatal_error "Invalid Mark Value ($mark) with HIGH_ROUTE_MARKS=Yes" if $config{HIGH_ROUTE_MARKS}; + } else { + fatal_error "Invalid Mark Value ($mark) with HIGH_ROUTE_MARKS=No" if ! $config{HIGH_ROUTE_MARKS}; + } + + for my $provider ( keys %providers ) { + my $num = $providers{$provider}{mark}; + fatal_error "Duplicate mark value ( $mark )" if $num == $val; + } + + + emit "qt ip rule del fwmark $mark"; + my $pref = 10000 + $val; + emit "run_ip rule add fwmark $mark pref $pref table $number"; + emit "echo \"qt ip rule del fwmark $mark\" >> \${VARDIR}/undo_routing"; + } + + $providers{$table} = {}; + $providers{$table}{number} = $number; + $providers{$table}{mark} = $val; + + my ( $loose, $optional ) = (0,0); + + unless ( $options eq '-' ) { + for my $option ( split /,/, $options ) { + if ( $option eq 'track' ) { + fatal_error "Interface $interface is tracked through an earlier provider" if $routemarked_interfaces{$interface}; + fatal_error "The 'track' option requires a numeric value in the MARK column - Provider \"$line\"" if $mark eq '-'; + $routemarked_interfaces{$interface} = $mark; + $routemarked_interfaces++; + } elsif ( $option =~ /^balance=(\d+)/ ) { + balance_default_route $1 , $gateway, $interface; + } elsif ( $option eq 'balance' ) { + balance_default_route 1 , $gateway, $interface; + } elsif ( $option eq 'loose' ) { + $loose = 1; + } elsif ( $option eq 'optional' ) { + $optional = 1; + } else { + fatal_error "Invalid option ($option) in provider \"$line\""; + } + } + } + + if ( $loose ) { + my $rulebase = 20000 + ( 256 * ( $number - 1 ) ); + + emit "\nrulenum=0\n"; + + emit "find_interface_addresses $interface | while read address; do"; + emit ' qt ip rule del from $address'; + emit " run_ip rule add from \$address pref \$(( $rulebase + \$rulenum )) table $number"; + emit " echo \"qt ip rule del from \$address\" >> \${VARDIR}/undo_routing"; + emit ' rulenum=$(($rulenum + 1))'; + emit 'done'; + } else { + emit "\nfind_interface_addresses $interface | while read address; do"; + emit ' qt ip rule del from $address'; + emit 'done'; + } + + emit "\nprogress_message \" Provider $table ($number) Added\"\n"; + + pop_indent; + emit 'else'; + + if ( $optional ) { + emit " error_message \"WARNING: Interface $interface is not configured -- Provider $table ($number) not Added\""; + emit " ${iface}_up="; + } else { + emit " fatal_error \"ERROR: Interface $interface is not configured -- Provider $table ($number) Cannot be Added\""; + } + + emit "fi\n"; + } + + sub add_an_rtrule( $$$$ ) { + my ( $source, $dest, $provider, $priority ) = @_; + + unless ( $providers{$provider} ) { + my $found = 0; + + if ( "\L$provider" =~ /^(0x[a-f0-9]+|0[0-7]*|[0-9]*)$/ ) { + my $provider_number = numeric_value $provider; + + for my $provider ( keys %providers ) { + if ( $providers{$provider}{number} == $provider_number ) { + $found = 1; + last; + } + } + } + + fatal_error "Unknown provider $provider in route rule \"$line\"" unless $found; + } + + $source = '-' unless $source; + $dest = '-' unless $dest; + + fatal_error "You must specify either the source or destination in an rt rule: \"$line\"" if $source eq '-' && $dest eq '-'; + + $dest = $dest eq '-' ? '' : "to $dest"; + + if ( $source eq '-' ) { + $source = ''; + } elsif ( $source =~ /:/ ) { + ( my $interface, $source ) = split /:/, $source; + $source = "iif $interface from $source"; + } elsif ( $source =~ /\..*\..*/ ) { + $source = "from $source"; + } else { + $source = "iif $source"; + } + + fatal_error "Invalid priority ($priority) in rule \"$line\"" unless $priority && $priority =~ /^\d{1,5}$/; + + $priority = "priority $priority"; + + emit "qt ip rule del $source $dest $priority"; + emit "run_ip rule add $source $dest $priority table $provider"; + emit "echo \"qt ip rule del $source $dest $priority\" >> \${VARDIR}/undo_routing"; + progress_message " Routing rule \"$line\" $done"; + } + # + # Setup_Providers() Starts Here.... + # + progress_message2 "$doing $fn ..."; + + emit "\nif [ -z \"\$NOROUTES\" ]; then"; + push_indent; + + emit "#\n# Undo any changes made since the last time that we [re]started -- this will not restore the default route\n#"; + emit 'undo_routing'; + emit "#\n# Save current routing table database so that it can be restored later\n#"; + emit 'cp /etc/iproute2/rt_tables ${VARDIR}/'; + emit "#\n# Capture the default route(s) if we don't have it (them) already.\n#"; + emit '[ -f ${VARDIR}/default_route ] || ip route ls | grep -E \'^\s*(default |nexthop )\' > ${VARDIR}/default_route'; + emit "#\n# Initialize the file that holds 'undo' commands\n#"; + emit '> ${VARDIR}/undo_routing'; + + save_progress_message 'Adding Providers...'; + + emit 'DEFAULT_ROUTE='; + + open PV, "$ENV{TMP_DIR}/providers" or fatal_error "Unable to open stripped providers file: $!"; + + while ( $line = ) { + chomp $line; + $line =~ s/\s+/ /g; + + my ( $table, $number, $mark, $duplicate, $interface, $gateway, $options, $copy, $extra ) = split /\s+/, $line; + + fatal_error "Invalid providers entry: $line" if $extra; + + add_a_provider( $table, $number, $mark, $duplicate, $interface, $gateway, $options, $copy ); + + push @providers, $table; + + $providers++; + + progress_message " Provider \"$line\" $done"; + + } + + close PV; + + if ( $providers ) { + if ( $balance ) { + emit 'if [ -n "$DEFAULT_ROUTE" ]; then'; + emit ' run_ip route replace default scope global $DEFAULT_ROUTE'; + emit " progress_message \"Default route '\$(echo \$DEFAULT_ROUTE | sed 's/\$\\s*//')' Added\""; + emit 'else'; + emit ' error_message "WARNING: No Default route added (all \'balance\' providers are down)"'; + emit ' restore_default_route'; + emit 'fi'; + emit ''; + } else { + emit "#\n# We don't have any 'balance' providers so we restore any default route that we've saved\n#"; + emit 'restore_default_route'; + } + + emit 'cat > /etc/iproute2/rt_tables <> /etc/iproute2/rt_tables"; + } + + if ( -s "$ENV{TMP_DIR}/route_rules" ) { + my $fn = find_file 'route_rules'; + progress_message2 "$doing $fn..."; + + emit ''; + + open RR, "$ENV{TMP_DIR}/route_rules" or fatal_error "Unable to open stripped route rules file: $!"; + + while ( $line = ) { + chomp $line; + $line =~ s/\s+/ /g; + + my ( $source, $dest, $provider, $priority, $extra ) = split /\s+/, $line; + + fatal_error "Invalid providers entry: $line" if $extra; + + add_an_rtrule( $source, $dest, $provider , $priority ); + } + + close RR; + } + } + + emit ''; + emit 'run_ip route flush cache'; + pop_indent; + emit "fi\n"; + + setup_route_marking if $routemarked_interfaces; + +} + +1; diff --git a/New/Shorewall/Tc.pm b/New/Shorewall/Tc.pm index 9b66e31af..8b25937b1 100644 --- a/New/Shorewall/Tc.pm +++ b/New/Shorewall/Tc.pm @@ -8,7 +8,7 @@ use Shorewall::Chains; use strict; our @ISA = qw(Exporter); -our @EXPORT = qw( process_tcrules ); +our @EXPORT = qw( process_tcrules setup_traffic_shaping ); our @EXPORT_OK = qw( process_tc_rule ); our @VERSION = 1.00; @@ -222,4 +222,8 @@ sub process_tcrules() { $comment = ''; } +sub setup_traffic_shaping() { + 1; +} + 1; diff --git a/New/compiler.pl b/New/compiler.pl index 98124ae73..16628561e 100755 --- a/New/compiler.pl +++ b/New/compiler.pl @@ -11,6 +11,7 @@ use Shorewall::Hosts; use Shorewall::Nat; use Shorewall::Tc; use Shorewall::Tunnels; +use Shorewall::Providers; # # Set to one if we find a SECTION @@ -2405,411 +2406,6 @@ sub generate_matrix() { } } -use constant { LOCAL_NUMBER => 255, - MAIN_NUMBER => 254, - DEFAULT_NUMBER => 253, - UNSPEC_NUMBER => 0 - }; - -my $balance = 0; -my $first_default_route = 1; - - -my %providers = ( 'local' => { number => LOCAL_NUMBER , mark => 0 } , - main => { number => MAIN_NUMBER , mark => 0 } , - default => { number => DEFAULT_NUMBER , mark => 0 } , - unspec => { number => UNSPEC_NUMBER , mark => 0 } ); - -my @providers; -my %routemarked_interfaces; -my $routemarked_interfaces = 0; - -sub setup_providers() { - my $fn = find_file 'providers'; - my $providers = 0; - - sub copy_table( $$ ) { - my ( $duplicate, $number ) = @_; - - emit "ip route show table $duplicate | while read net route; do"; - emit ' case $net in'; - emit ' default|nexthop)'; - emit ' ;;'; - emit ' *)'; - emit " run_ip route add table $number \$net \$route"; - emit ' ;;'; - emit ' esac'; - emit "done\n"; - } - - sub copy_and_edit_table( $$$ ) { - my ( $duplicate, $number, $copy ) = @_; - - my $match = $copy; - - $match =~ s/ /\|/g; - - emit "ip route show table $duplicate | while read net route; do"; - emit ' case $net in'; - emit ' default|nexthop)'; - emit ' ;;'; - emit ' *)'; - emit " run_ip route add table $number \$net \$route"; - emit ' case $(find_device $route) in'; - emit " $match)"; - emit " run_ip route add table $number \$net \$route"; - emit ' ;;'; - emit ' esac'; - emit ' ;;'; - emit ' esac'; - emit "done\n"; - } - - sub balance_default_route( $$$ ) { - my ( $weight, $gateway, $interface ) = @_; - - $balance = 1; - - emit ''; - - if ( $first_default_route ) { - if ( $gateway ) { - emit "DEFAULT_ROUTE=\"nexthop via $gateway dev $interface weight $weight\""; - } else { - emit "DEFAULT_ROUTE=\"nexthop dev $interface weight $weight\""; - } - - $first_default_route = 0; - } else { - if ( $gateway ) { - emit "DEFAULT_ROUTE=\"\$DEFAULT_ROUTE nexthop via $gateway dev $interface weight $weight\""; - } else { - emit "DEFAULT_ROUTE=\"\$DEFAULT_ROUTE nexthop dev $interface weight $weight\""; - } - } - } - - sub add_a_provider( $$$$$$$$ ) { - - my ($table, $number, $mark, $duplicate, $interface, $gateway, $options, $copy) = @_; - - fatal_error 'Providers require mangle support in your kernel and iptables' unless $capabilities{MANGLE_ENABLED}; - - fatal_error "Duplicate provider ( $table )" if $providers{$table}; - - for my $provider ( keys %providers ) { - fatal_error "Duplicate provider number ( $number )" if $providers{$provider}{number} == $number; - } - - emit "#\n# Add Provider $table ($number)\n#"; - - emit "if interface_is_usable $interface; then"; - push_indent; - my $iface = chain_base $interface; - - emit "${iface}_up=Yes"; - emit "qt ip route flush table $number"; - emit "echo \"qt ip route flush table $number\" >> \${VARDIR}/undo_routing"; - - $duplicate = '-' unless $duplicate; - $copy = '-' unless $copy; - - if ( $duplicate ne '-' ) { - if ( $copy ne '-' ) { - if ( $copy eq 'none' ) { - $copy = $interface; - } else { - my @c = ( split /,/, $copy ); - $copy = "@c"; - } - - copy_and_edit_table( $duplicate, $number ,$copy ); - } else { - copy_table ( $duplicate, $number ); - } - } else { - fatal_error 'A non-empty COPY column requires that a routing table be specified in the DUPLICATE column' if $copy ne '-'; - } - - $gateway = '-' unless $gateway; - - if ( $gateway eq 'detect' ) { - emit "gateway=\$(detect_gateway $interface)\n"; - - emit 'if [ -n "$gateway" ]; then'; - emit " run_ip route replace \$gateway src \$(find_first_interface_address $interface) dev $interface table $number"; - emit " run_ip route add default via \$gateway dev $interface table $number"; - emit 'else'; - emit " fatal_error \"Unable to detect the gateway through interface $interface\""; - emit "fi\n"; - } elsif ( $gateway && $gateway ne '-' ) { - emit "run_ip route replace $gateway src \$(find_first_interface_address $interface) dev $interface table $number"; - emit "run_ip route add default via $gateway dev $interface table $number"; - } else { - $gateway = ''; - emit "run_ip route add default dev $interface table $number"; - } - - $mark = '-' unless $mark; - - my $val = 0; - - if ( $mark ne '-' ) { - - $val = numeric_value $mark; - - verify_mark $mark; - - if ( $val < 256) { - fatal_error "Invalid Mark Value ($mark) with HIGH_ROUTE_MARKS=Yes" if $config{HIGH_ROUTE_MARKS}; - } else { - fatal_error "Invalid Mark Value ($mark) with HIGH_ROUTE_MARKS=No" if ! $config{HIGH_ROUTE_MARKS}; - } - - for my $provider ( keys %providers ) { - my $num = $providers{$provider}{mark}; - fatal_error "Duplicate mark value ( $mark )" if $num == $val; - } - - - emit "qt ip rule del fwmark $mark"; - my $pref = 10000 + $val; - emit "run_ip rule add fwmark $mark pref $pref table $number"; - emit "echo \"qt ip rule del fwmark $mark\" >> \${VARDIR}/undo_routing"; - } - - $providers{$table} = {}; - $providers{$table}{number} = $number; - $providers{$table}{mark} = $val; - - my ( $loose, $optional ) = (0,0); - - unless ( $options eq '-' ) { - for my $option ( split /,/, $options ) { - if ( $option eq 'track' ) { - fatal_error "Interface $interface is tracked through an earlier provider" if $routemarked_interfaces{$interface}; - fatal_error "The 'track' option requires a numeric value in the MARK column - Provider \"$line\"" if $mark eq '-'; - $routemarked_interfaces{$interface} = $mark; - $routemarked_interfaces++; - } elsif ( $option =~ /^balance=(\d+)/ ) { - balance_default_route $1 , $gateway, $interface; - } elsif ( $option eq 'balance' ) { - balance_default_route 1 , $gateway, $interface; - } elsif ( $option eq 'loose' ) { - $loose = 1; - } elsif ( $option eq 'optional' ) { - $optional = 1; - } else { - fatal_error "Invalid option ($option) in provider \"$line\""; - } - } - } - - if ( $loose ) { - my $rulebase = 20000 + ( 256 * ( $number - 1 ) ); - - emit "\nrulenum=0\n"; - - emit "find_interface_addresses $interface | while read address; do"; - emit ' qt ip rule del from $address'; - emit " run_ip rule add from \$address pref \$(( $rulebase + \$rulenum )) table $number"; - emit " echo \"qt ip rule del from \$address\" >> \${VARDIR}/undo_routing"; - emit ' rulenum=$(($rulenum + 1))'; - emit 'done'; - } else { - emit "\nfind_interface_addresses $interface | while read address; do"; - emit ' qt ip rule del from $address'; - emit 'done'; - } - - emit "\nprogress_message \" Provider $table ($number) Added\"\n"; - - pop_indent; - emit 'else'; - - if ( $optional ) { - emit " error_message \"WARNING: Interface $interface is not configured -- Provider $table ($number) not Added\""; - emit " ${iface}_up="; - } else { - emit " fatal_error \"ERROR: Interface $interface is not configured -- Provider $table ($number) Cannot be Added\""; - } - - emit "fi\n"; - } - - sub add_an_rtrule( $$$$ ) { - my ( $source, $dest, $provider, $priority ) = @_; - - unless ( $providers{$provider} ) { - my $found = 0; - - if ( "\L$provider" =~ /^(0x[a-f0-9]+|0[0-7]*|[0-9]*)$/ ) { - my $provider_number = numeric_value $provider; - - for my $provider ( keys %providers ) { - if ( $providers{$provider}{number} == $provider_number ) { - $found = 1; - last; - } - } - } - - fatal_error "Unknown provider $provider in route rule \"$line\"" unless $found; - } - - $source = '-' unless $source; - $dest = '-' unless $dest; - - fatal_error "You must specify either the source or destination in an rt rule: \"$line\"" if $source eq '-' && $dest eq '-'; - - $dest = $dest eq '-' ? '' : "to $dest"; - - if ( $source eq '-' ) { - $source = ''; - } elsif ( $source =~ /:/ ) { - ( my $interface, $source ) = split /:/, $source; - $source = "iif $interface from $source"; - } elsif ( $source =~ /\..*\..*/ ) { - $source = "from $source"; - } else { - $source = "iif $source"; - } - - fatal_error "Invalid priority ($priority) in rule \"$line\"" unless $priority && $priority =~ /^\d{1,5}$/; - - $priority = "priority $priority"; - - emit "qt ip rule del $source $dest $priority"; - emit "run_ip rule add $source $dest $priority table $provider"; - emit "echo \"qt ip rule del $source $dest $priority\" >> \${VARDIR}/undo_routing"; - progress_message " Routing rule \"$line\" $done"; - } - # - # Setup_Providers() Starts Here.... - # - progress_message2 "$doing $fn ..."; - - emit "\nif [ -z \"\$NOROUTES\" ]; then"; - push_indent; - - emit "#\n# Undo any changes made since the last time that we [re]started -- this will not restore the default route\n#"; - emit 'undo_routing'; - emit "#\n# Save current routing table database so that it can be restored later\n#"; - emit 'cp /etc/iproute2/rt_tables ${VARDIR}/'; - emit "#\n# Capture the default route(s) if we don't have it (them) already.\n#"; - emit '[ -f ${VARDIR}/default_route ] || ip route ls | grep -E \'^\s*(default |nexthop )\' > ${VARDIR}/default_route'; - emit "#\n# Initialize the file that holds 'undo' commands\n#"; - emit '> ${VARDIR}/undo_routing'; - - save_progress_message 'Adding Providers...'; - - emit 'DEFAULT_ROUTE='; - - open PV, "$ENV{TMP_DIR}/providers" or fatal_error "Unable to open stripped providers file: $!"; - - while ( $line = ) { - chomp $line; - $line =~ s/\s+/ /g; - - my ( $table, $number, $mark, $duplicate, $interface, $gateway, $options, $copy, $extra ) = split /\s+/, $line; - - fatal_error "Invalid providers entry: $line" if $extra; - - add_a_provider( $table, $number, $mark, $duplicate, $interface, $gateway, $options, $copy ); - - push @providers, $table; - - $providers++; - - progress_message " Provider \"$line\" $done"; - - } - - close PV; - - if ( $providers ) { - if ( $balance ) { - emit 'if [ -n "$DEFAULT_ROUTE" ]; then'; - emit ' run_ip route replace default scope global $DEFAULT_ROUTE'; - emit " progress_message \"Default route '\$(echo \$DEFAULT_ROUTE | sed 's/\$\\s*//')' Added\""; - emit 'else'; - emit ' error_message "WARNING: No Default route added (all \'balance\' providers are down)"'; - emit ' restore_default_route'; - emit 'fi'; - emit ''; - } else { - emit "#\n# We don't have any 'balance' providers so we restore any default route that we've saved\n#"; - emit 'restore_default_route'; - } - - emit 'cat > /etc/iproute2/rt_tables <> /etc/iproute2/rt_tables"; - } - - if ( -s "$ENV{TMP_DIR}/route_rules" ) { - my $fn = find_file 'route_rules'; - progress_message2 "$doing $fn..."; - - emit ''; - - open RR, "$ENV{TMP_DIR}/route_rules" or fatal_error "Unable to open stripped route rules file: $!"; - - while ( $line = ) { - chomp $line; - $line =~ s/\s+/ /g; - - my ( $source, $dest, $provider, $priority, $extra ) = split /\s+/, $line; - - fatal_error "Invalid providers entry: $line" if $extra; - - add_an_rtrule( $source, $dest, $provider , $priority ); - } - - close RR; - } - } - - emit ''; - emit 'run_ip route flush cache'; - pop_indent; - emit "fi\n" -} - -# -# Set up marking for 'tracked' interfaces. Unline in Shorewall 3.x, we add these rules inconditionally, even if the associated interface isn't up. -# -sub setup_route_marking() { - my $mask = $config{HIGH_ROUTE_MARKS} ? '0xFFFF' : '0xFF'; - my $mark_op = $config{HIGH_ROUTE_MARKS} ? '--or-mark' : '--set-mark'; - - add_rule $mangle_table->{PREROUTING} , "-m connmark ! --mark 0/$mask -j CONNMARK --restore-mark --mask $mask"; - add_rule $mangle_table->{OUTPUT} , " -m connmark ! --mark 0/$mask -j CONNMARK --restore-mark --mask $mask"; - - my $chainref = new_chain 'mangle', 'routemark'; - - while ( my ( $interface, $mark ) = ( each %routemarked_interfaces ) ) { - add_rule $mangle_table->{PREROUTING} , "-i $interface -m mark --mark 0/$mask -j routemark"; - add_rule $chainref, " -i $interface -j MARK $mark_op $mark"; - } - - add_rule $chainref, "-m mark ! --mark 0/$mask -j CONNMARK --save-mark --mask $mask"; -} - -sub setup_traffic_shaping() { -} - sub generate_script_1 { copy find_file 'prog.header'; @@ -3058,7 +2654,6 @@ sub compile_firewall( $ ) { # if ( -s "$ENV{TMP_DIR}/providers" ) { setup_providers; - setup_route_marking if $routemarked_interfaces; } else { emit "\nundo_routing"; emit 'restore_default_route';