diff --git a/Samples/one-interface/shorewall.conf b/Samples/one-interface/shorewall.conf index 19e555ec2..ab4ee27c4 100644 --- a/Samples/one-interface/shorewall.conf +++ b/Samples/one-interface/shorewall.conf @@ -188,6 +188,8 @@ MANGLE_ENABLED=Yes AUTOMAKE=No +WIDE_TC_MARKS=Yes + ############################################################################### # P A C K E T D I S P O S I T I O N ############################################################################### diff --git a/Samples/three-interfaces/shorewall.conf b/Samples/three-interfaces/shorewall.conf index 72803a79d..d9b75c693 100644 --- a/Samples/three-interfaces/shorewall.conf +++ b/Samples/three-interfaces/shorewall.conf @@ -188,6 +188,8 @@ MANGLE_ENABLED=Yes AUTOMAKE=No +WIDE_TC_MARKS=Yes + ############################################################################### # P A C K E T D I S P O S I T I O N ############################################################################### diff --git a/Samples/two-interfaces/shorewall.conf b/Samples/two-interfaces/shorewall.conf index a86fde804..71706010c 100644 --- a/Samples/two-interfaces/shorewall.conf +++ b/Samples/two-interfaces/shorewall.conf @@ -188,6 +188,8 @@ MANGLE_ENABLED=Yes AUTOMAKE=No +WIDE_TC_MARKS=Yes + ############################################################################### # P A C K E T D I S P O S I T I O N ############################################################################### diff --git a/Samples6/one-interface/shorewall6.conf b/Samples6/one-interface/shorewall6.conf index 789be9c3f..3b81dae77 100644 --- a/Samples6/one-interface/shorewall6.conf +++ b/Samples6/one-interface/shorewall6.conf @@ -137,6 +137,8 @@ MANGLE_ENABLED=Yes AUTOMAKE=No +WIDE_TC_MARKS=Yes + ############################################################################### # P A C K E T D I S P O S I T I O N ############################################################################### diff --git a/Samples6/three-interfaces/shorewall6.conf b/Samples6/three-interfaces/shorewall6.conf index f07e36e71..df0faa3c6 100644 --- a/Samples6/three-interfaces/shorewall6.conf +++ b/Samples6/three-interfaces/shorewall6.conf @@ -137,6 +137,8 @@ MANGLE_ENABLED=Yes AUTOMAKE=No +WIDE_TC_MARKS=Yes + ############################################################################### # P A C K E T D I S P O S I T I O N ############################################################################### diff --git a/Samples6/two-interfaces/shorewall6.conf b/Samples6/two-interfaces/shorewall6.conf index ecf9d18dd..092be2273 100644 --- a/Samples6/two-interfaces/shorewall6.conf +++ b/Samples6/two-interfaces/shorewall6.conf @@ -137,6 +137,8 @@ MANGLE_ENABLED=Yes AUTOMAKE=No +WIDE_TC_MARKS=Yes + ############################################################################### # P A C K E T D I S P O S I T I O N ############################################################################### diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 4e23a88fb..f8f68e2a4 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -1482,19 +1482,34 @@ sub mac_match( $ ) { # sub verify_mark( $ ) { my $mark = $_[0]; - my $limit = $config{HIGH_ROUTE_MARKS} ? 0xFFFF : 0xFF; + my $limit; + my $mask; my $value = numeric_value( $mark ); + if ( $config{HIGH_ROUTE_MARKS} ) { + if ( $config{WIDE_TC_MARKS} ) { + $limit = 0xFFFFFF; + $mask = 0xFFFF; + } else { + $limit = 0xFFFF; + $mask = 0xFF; + } + } elsif ( $config{WIDE_TC_MARKS} ) { + $limit = $mask = 0x3FFF; + } else { + $limit = $mask = 0xFF; + } + fatal_error "Invalid Mark or Mask value ($mark)" unless defined( $value ) && $value <= $limit; fatal_error "Invalid High Mark or Mask value ($mark)" - if ( $value > 0xFF && $value & 0xFF ); + if ( $value > $mask && $value & $mask ); } sub verify_small_mark( $ ) { verify_mark ( (my $mark) = $_[0] ); - fatal_error "Mark value ($mark) too large" if numeric_value( $mark ) > 0xFF; + fatal_error "Mark value ($mark) too large" if numeric_value( $mark ) > ( $config{WIDE_TC_MARKS} ? 0x03FF : 0xFF ); } sub validate_mark( $ ) { diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm index ca46af6ae..130051d0e 100644 --- a/Shorewall/Perl/Shorewall/Config.pm +++ b/Shorewall/Perl/Shorewall/Config.pm @@ -434,6 +434,7 @@ sub initialize( $ ) { RESTORE_DEFAULT_ROUTE => undef , FAST_STOP => undef , AUTOMAKE => undef , + WIDE_TC_MARKS => undef, # # Packet Disposition # @@ -536,6 +537,7 @@ sub initialize( $ ) { AUTO_COMMENT => undef, MANGLE_ENABLED => undef , AUTOMAKE => undef , + WIDE_TC_MARKS => undef, # # Packet Disposition # @@ -733,15 +735,19 @@ sub assert( $ ) { # Convert value to decimal number # sub numeric_value ( $ ) { + no warnings; my $mark = lc $_[0]; return undef unless $mark =~ /^-?(0x[a-f0-9]+|0[0-7]*|[1-9]\d*)$/; $mark =~ /^0/ ? oct $mark : $mark; + use warnings; } sub numeric_value1 ( $ ) { + no warnings; my $val = numeric_value $_[0]; fatal_error "Invalid Number ($_[0])" unless defined $val; $val; + use warnings; } # @@ -2286,6 +2292,7 @@ sub get_configuration( $ ) { default_yes_no 'USE_DEFAULT_RT' , ''; default_yes_no 'RESTORE_DEFAULT_ROUTE' , 'Yes'; default_yes_no 'AUTOMAKE' , ''; + default_yes_no 'WIDE_TC_MARKS' , ''; $capabilities{XCONNMARK} = '' unless $capabilities{XCONNMARK_MATCH} and $capabilities{XMARK}; diff --git a/Shorewall/Perl/Shorewall/Providers.pm b/Shorewall/Perl/Shorewall/Providers.pm index 77847b76c..12d94a563 100644 --- a/Shorewall/Perl/Shorewall/Providers.pm +++ b/Shorewall/Perl/Shorewall/Providers.pm @@ -93,7 +93,7 @@ INIT { # Set up marking for 'tracked' interfaces. # sub setup_route_marking() { - my $mask = $config{HIGH_ROUTE_MARKS} ? '0xFF00' : '0xFF'; + my $mask = $config{HIGH_ROUTE_MARKS} ? $config{WIDE_TC_MARKS} ? '0xFF0000' : '0xFF00' : '0xFF'; require_capability( 'CONNMARK_MATCH' , 'the provider \'track\' option' , 's' ); require_capability( 'CONNMARK' , 'the provider \'track\' option' , 's' ); @@ -292,14 +292,17 @@ sub add_a_provider( $$$$$$$$ ) { verify_mark $mark; - if ( $val < 256) { + if ( $val < 65535 ) { + fatal_error "Invalid Mark Value ($mark) with WIDE_TC_MARKS=No" unless $config{WIDE_TC_MARKS}; + fatal_error "Invalid Mark Value ($mark) with HIGH_ROUTE_MARKS=No" unless $config{HIGH_ROUTE_MARKS}; + } elsif ( $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}; + fatal_error "Invalid Mark Value ($mark) with HIGH_ROUTE_MARKS=No" unless $config{HIGH_ROUTE_MARKS}; } for my $providerref ( values %providers ) { - fatal_error "Duplicate mark value ($mark)" if $providerref->{mark} == $val; + fatal_error "Duplicate mark value ($mark)" if numeric_value( $providerref->{mark} ) == $val; } $pref = 10000 + $number - 1; @@ -354,7 +357,7 @@ sub add_a_provider( $$$$$$$$ ) { $providers{$table} = { provider => $table, number => $number , - mark => $val , + mark => $val ? in_hex($val) : $val , interface => $interface , optional => $optional , gateway => $gateway , @@ -782,7 +785,7 @@ sub lookup_provider( $ ) { # sub handle_stickiness( $ ) { my $havesticky = shift; - my $mask = $config{HIGH_ROUTE_MARKS} ? '0xFF00' : '0xFF'; + my $mask = $config{HIGH_ROUTE_MARKS} ? $config{WIDE_TC_MARKS} ? '0xFF0000' : '0xFF00' : '0xFF'; my $setstickyref = $mangle_table->{setsticky}; my $setstickoref = $mangle_table->{setsticko}; my $tcpreref = $mangle_table->{tcpre}; diff --git a/Shorewall/Perl/Shorewall/Tc.pm b/Shorewall/Perl/Shorewall/Tc.pm index 80ca3a98a..031614369 100644 --- a/Shorewall/Perl/Shorewall/Tc.pm +++ b/Shorewall/Perl/Shorewall/Tc.pm @@ -316,19 +316,19 @@ sub process_tc_rule( $$$$$$$$$$$$ ) { if ( defined $m1 && $m1 ne '' ) { $val = numeric_value ($m1); - fatal_error "Invalid Mask ($m1)" unless defined $val; + fatal_error "Invalid Mask ($m1)" unless defined $val && $val && $val <= 0xffffffff; $mask1 = $m1; } if ( defined $m2 && $m2 ne '' ) { $val = numeric_value ($m2); - fatal_error "Invalid Mask ($m2)" unless defined $val; + fatal_error "Invalid Mask ($m2)" unless defined $val && $val <= 0xffffffff; $mask2 = $m2; } if ( defined $s ) { $val = numeric_value ($s); - fatal_error "Invalid Shift Bits ($s)" unless defined $val; + fatal_error "Invalid Shift Bits ($s)" unless defined $val && $val < 128; $shift = $s; } } else { @@ -361,8 +361,9 @@ sub process_tc_rule( $$$$$$$$$$$$ ) { if ( $config{HIGH_ROUTE_MARKS} ) { my $val = numeric_value( $cmd ); fatal_error "Invalid MARK/CLASSIFY ($cmd)" unless defined $val; - fatal_error 'Marks < 256 may not be set in the PREROUTING or OUTPUT chains when HIGH_ROUTE_MARKS=Yes' - if $cmd && ( $chain eq 'tcpre' || $chain eq 'tcout' ) && $val <= 0xFF; + my $limit = $config{WIDE_TC_MARKS} ? 65535 : 255; + fatal_error "Marks <= $limit may not be set in the PREROUTING or OUTPUT chains when HIGH_ROUTE_MARKS=Yes" + if $cmd && ( $chain eq 'tcpre' || $chain eq 'tcout' ) && $val <= $limit; } } } @@ -598,7 +599,7 @@ sub validate_tc_class( $$$$$$ ) { $markval = numeric_value( $mark ); fatal_error "Invalid MARK ($markval)" unless defined $markval; - $classnumber = ( $devref->{number} << 10 ) | $mark; + $classnumber = $config{WIDE_TC_MARKS} ? ( $devref->{number} << 10 ) | $mark : $devref->{number} . $mark; fatal_error "Duplicate MARK ($mark)" if $tcref->{$classnumber}; } } else { @@ -1007,7 +1008,7 @@ sub setup_tc() { my $mark_part = ''; if ( @routemarked_interfaces && ! $config{TC_EXPERT} ) { - $mark_part = $config{HIGH_ROUTE_MARKS} ? '-m mark --mark 0/0xFF00' : '-m mark --mark 0/0xFF'; + $mark_part = $config{HIGH_ROUTE_MARKS} ? $config{WIDE_TC_MARKS} ? '-m mark --mark 0/0xFF0000' : '-m mark --mark 0/0xFF00' : '-m mark --mark 0/0xFF'; for my $interface ( @routemarked_interfaces ) { add_rule $mangle_table->{PREROUTING} , "-i $interface -j tcpre"; @@ -1024,7 +1025,7 @@ sub setup_tc() { if ( $config{HIGH_ROUTE_MARKS} ) { for my $chain qw(INPUT FORWARD POSTROUTING) { - insert_rule1 $mangle_table->{$chain}, 0, '-j MARK --and-mark 0xFF'; + insert_rule1 $mangle_table->{$chain}, 0, $config{WIDE_TC_MARKS} ? '-j MARK --and-mark 0x03FF' : '-j MARK --and-mark 0xFF'; } } } diff --git a/Shorewall/changelog.txt b/Shorewall/changelog.txt index 30ba0ac62..b1dd65e91 100644 --- a/Shorewall/changelog.txt +++ b/Shorewall/changelog.txt @@ -1,6 +1,8 @@ Changes in Shorewall 4.3.10 -None. +1) Fix handling of shared optional providers. + +2) Add WIDE_TC_MARKS option. Changes in Shorewall 4.3.9 diff --git a/Shorewall/configfiles/shorewall.conf b/Shorewall/configfiles/shorewall.conf index 558184d3d..e3694ba8e 100644 --- a/Shorewall/configfiles/shorewall.conf +++ b/Shorewall/configfiles/shorewall.conf @@ -197,6 +197,8 @@ FAST_STOP=No AUTOMAKE=No +WIDE_TC_MARKS=No + ############################################################################### # P A C K E T D I S P O S I T I O N ############################################################################### diff --git a/Shorewall/releasenotes.txt b/Shorewall/releasenotes.txt index 70bb6c4c2..107885791 100644 --- a/Shorewall/releasenotes.txt +++ b/Shorewall/releasenotes.txt @@ -59,7 +59,12 @@ released late in 2009. P R O B L E M S C O R R E C T E D I N 4 . 3 . 10 ---------------------------------------------------------------------------- -None. +1. When Shorewall could not determine the MAC address of of a gateway + router where multiple providers are configured through the same + interface, invalid iptables-restore input was generated. This + resulted in an error message similar to the following: + + iptables-restore v1.3.5: Bad mac address `-j' ---------------------------------------------------------------------------- K N O W N P R O B L E M S R E M A I N I N G @@ -71,7 +76,29 @@ None. N E W F E A T U R E S I N 4 . 3 . 10 ---------------------------------------------------------------------------- -None. +1. The change that implemented IPMARK support in 4.3.9 resulted in a + lack of upward compatibility which could break some + configurations. The incompatibility stems from the way in which + Shorewall generates a TC class Id from a mark value. + + - Prior to 4.3.9, the class number was constructed by concatinating + the device number with the mark value. + + - Beginning with 4.3.9, the class number is constructed by shifting + the device number left by 10 bits and logically ORing the result + with the mark value. + + The WIDE_TC_MARKS option in shorewall.conf selects which + construction to use. WIDE_TC_MARKS=No (the default) produces + pre-4.3.9 behavior. WIDE_TC_MARKS=Yes produces the new behavior. + + In addition to determining the method of constructing class Ids, + WIDE_TC_MARKS=Yes provides for larger mark values for traffic + shaping. Traffic shaping marks may have values up to 1023 with + WIDE_TC_MARKS=Yes. This means that when both WIDE_TC_MARKS=Yes and + HIGH_ROUTE_MARKS=Yes, routing marks (/etc/shorewall/providers MARK + column) must be >= 65536 (0x10000) and must be a multiple of 65536 + (0x1000, 0x20000, 0x30000, ...). ---------------------------------------------------------------------------- N E W F E A T U R E S IN 4 . 3 @@ -436,7 +463,7 @@ None. IPMARK(dst, 0XFF00, 0x8000,8) - Destination IP address is 192.168.4.3 = 0xc0a80103 + Destination IP address is 192.168.4.3 = 0xc0a80403 0xc0a80403 LAND 0xFF00 = 0x0400 0x0400 LOR 0x80 = 0x8400 diff --git a/Shorewall6/lib.base b/Shorewall6/lib.base index aa5d85753..e2a8da809 100644 --- a/Shorewall6/lib.base +++ b/Shorewall6/lib.base @@ -33,7 +33,7 @@ # SHOREWALL_LIBVERSION=40300 -SHOREWALL_CAPVERSION=40205 +SHOREWALL_CAPVERSION=40309 [ -n "${VARDIR:=/var/lib/shorewall6}" ] [ -n "${SHAREDIR:=/usr/share/shorewall6}" ] diff --git a/Shorewall6/shorewall6.conf b/Shorewall6/shorewall6.conf index 238b92d4e..19b00b3b3 100644 --- a/Shorewall6/shorewall6.conf +++ b/Shorewall6/shorewall6.conf @@ -143,6 +143,8 @@ MANGLE_ENABLED=Yes AUTOMAKE=No +WIDE_TC_MARKS=No + ############################################################################### # P A C K E T D I S P O S I T I O N ###############################################################################