diff --git a/Shorewall/Perl/Shorewall/Tc.pm b/Shorewall/Perl/Shorewall/Tc.pm index b3b70039e..83338a7a6 100644 --- a/Shorewall/Perl/Shorewall/Tc.pm +++ b/Shorewall/Perl/Shorewall/Tc.pm @@ -103,6 +103,12 @@ our @tccmd = ( { match => sub ( $ ) { $_[0] eq 'SAVE' } , mask => '' , connmark => 0 } , + { match => sub ( $ ) { $_[0] =~ /^IPMARK/ }, + target => 'IPMARK' , + mark => NOMARK, + mask => '', + connmark => 0 + } , { match => sub ( $ ) { $_[0] =~ '\|.*'} , target => 'MARK --or-mark' , mark => HIGHMARK , @@ -293,6 +299,43 @@ sub process_tc_rule( $$$$$$$$$$$$ ) { } $sticky++; + } elsif ( $target eq 'IPMARK ' ) { + my ( $srcdst, $mask1, $mask2, $shift ) = ('src', 255, 0, 0 ); + + require_capability 'IPMARK_TARGET', 'IPMARK', 's'; + + if ( $cmd =~ /^IPMARK\((.+?)\)$/ ) { + my $params = $1; + my $val; + + my ( $sd, $m1, $m2, $s , $bad ) = split ',', $params; + + fatal_error "Invalid IPMARK parameters ($params)" if $bad; + fatal_error "Invalid IPMARK parameter ($sd)" unless ( $sd eq 'src' || $sd eq 'dst' ); + $srcdst = $sd; + + if ( defined $m1 && $m1 ne '' ) { + $val = numeric_value ($m1); + 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 && $val <= 0xffffffff; + $mask2 = $m2; + } + + if ( defined $s ) { + $val = numeric_value ($s); + fatal_error "Invalid Shift Bits ($s)" unless defined $val && $val < 128; + $shift = $s; + } + } else { + fatal_error "Invalid MARK/CLASSIFY ($cmd)" unless $cmd eq 'IPMARK'; + } + + $target = "IPMARK --addr $srcdst --and-mask $mask1 --or-mask $mask2 --shift $shift"; } if ( $rest ) { @@ -573,7 +616,7 @@ sub validate_tc_class( $$$$$$ ) { flow => '' , pfifo => 0, occurs => 1, - src => 0, + src => 1, }; $tcref = $tcref->{$classnumber}; @@ -588,24 +631,24 @@ sub validate_tc_class( $$$$$$ ) { if ( $option eq 'default' ) { fatal_error "Only one default class may be specified for device $device" if $devref->{default}; - fatal_error q(The 'default' option is not valid with 'occurs') if $tcref->{occurs} > 1; + fatal_error "The $option option is not valid with 'occurs" if $tcref->{occurs} > 1; $devref->{default} = $classnumber; } elsif ( $option eq 'tcp-ack' ) { - fatal_error q(The 'tcp-ack' option is not valid with 'occurs') if $tcref->{occurs} > 1; + fatal_error "The $option option is not valid with 'occurs" if $tcref->{occurs} > 1; $tcref->{tcp_ack} = 1; } elsif ( $option =~ /^tos=0x[0-9a-f]{2}$/ ) { - fatal_error q(The 'tos' option is not valid with 'occurs') if $tcref->{occurs} > 1; + fatal_error "The $option option is not valid with 'occurs" if $tcref->{occurs} > 1; ( undef, $option ) = split /=/, $option; push @{$tcref->{tos}}, "$option/0xff"; } elsif ( $option =~ /^tos=0x[0-9a-f]{2}\/0x[0-9a-f]{2}$/ ) { - fatal_error q(The 'tos' option is not valid with 'occurs') if $tcref->{occurs} > 1; + fatal_error "The $option option is not valid with 'occurs" if $tcref->{occurs} > 1; ( undef, $option ) = split /=/, $option; push @{$tcref->{tos}}, $option; } elsif ( $option =~ /^flow=(.*)$/ ) { - fatal_error q(The 'flow' option is not allowed with 'pfifo') if $tcref->{pfifo}; + fatal_error "The 'flow' option is not allowed with 'pfifo'" if $tcref->{pfifo}; $tcref->{flow} = process_flow $1; } elsif ( $option eq 'pfifo' ) { - fatal_error q(The 'pfifo'' option is not allowed with 'flow=') if $tcref->{flow}; + fatal_error "The 'pfifo'' option is not allowed with 'flow='" if $tcref->{flow}; $tcref->{pfifo} = 1; } elsif ( $option =~ /^occurs=((\d+)([ds]?))$/ ) { my $val = $2; @@ -616,10 +659,8 @@ sub validate_tc_class( $$$$$$ ) { fatal_error "Invalid 'occurs' ($val)" unless defined $occurs && $occurs > 1 && $occurs <= 256; fatal_error "Invalid 'occurs' ($val)" if $occurs > ( $config{WIDE_TC_MARKS} ? 8191 : 255 ); fatal_error q(Duplicate 'occurs') if $tcref->{occurs} > 1; - fatal_error q(The 'occurs' option is only valid with 'classify') unless $devref->{classify}; fatal_error q(The 'occurs' option is not valid with 'default') if $devref->{default} == $classnumber; fatal_error q(The 'occurs' option is not valid with 'tos') if @{$tcref->{tos}}; - $tcref->{occurs} = $occurs; } else { fatal_error "Unknown option ($option)"; diff --git a/Shorewall/changelog.txt b/Shorewall/changelog.txt index aee024b46..b41e617f6 100644 --- a/Shorewall/changelog.txt +++ b/Shorewall/changelog.txt @@ -13,9 +13,7 @@ Changes in Shorewall 4.3.10 6) Fix handling of 'all' in the SOURCE of DNAT- rules. -7) Remove IPMARK support. - -8) Fix compile for export. +7) Fix compile for export. Changes in Shorewall 4.3.9 diff --git a/Shorewall/releasenotes.txt b/Shorewall/releasenotes.txt index ffd8f4d15..48ba5fa26 100644 --- a/Shorewall/releasenotes.txt +++ b/Shorewall/releasenotes.txt @@ -77,7 +77,15 @@ released late in 2009. iptables-restore v1.3.5: Bad mac address `-j' -2. Previously, when 'all' appeared in the SOURCE column of a DNAT- +2. Previously, Shorewall has treated traffic shaping class IDs as + decimal numbers (or pairs of decimal numbers). That worked fine + until IPMARK was implemented. IPMARK requires Shorewall to generate + class Ids in numeric sequence. In 4.3.9, that didn't work correctly + because Shorewall was generating the sequence "..8,9,10,11..." when + the correct sequence was "...8,9,a,b,...". Shorewall now treats + class IDs as hex, like 'tc' and 'iptables' do. + +3. Previously, when 'all' appeared in the SOURCE column of a DNAT- rule, no rule was generated to redirect output from the firewall itself. @@ -119,75 +127,7 @@ None. column) must be >= 65536 (0x10000) and must be a multiple of 65536 (0x1000, 0x20000, 0x30000, ...). -2) The IPMARK implementation in 4.3.9 has been replaced with a - different facility that is much more efficient. A feature similar - to IPMARK will be re-introduced once there is a useable IPCLASSIFY - implementation (Like IPMARK but sets the classid directly). - -16) There has been a desire in the user community to limit traffic by - IP address using Shorewall traffic shaping. Heretofore, that has - required a very inefficient process: - - a) Define a tcclass for each internal host (two, if shaping both in - and out). - b) Define a tcrule for each host to mark to classify the packets - accordingly. - - Beginning with Shorewall 4.3.10, this process is made easier, at - least for download traffic where shaping occurs on the firewall's - internal interface(s). - - The new facility has two components: - - a) A new 'occurs' OPTION in /etc/shorewall/tcclasses. - b) New semantic behavior for entries in /etc/shorewall/tcrules that - refer to a class defined with 'occurs'. - - The 'occurs' option causes the class definition to be replicated - many times. The synax is: - - occurs=[d|s] - - The 'd' and 's' specify whether the occuring class should have one - occurrance for each destination IP address (d) or each source IP - address (s). The default is 'd'. - - When 'occurs' is used: - - a) The associated device must have the 'classify' option. - b) The class may not be the default class. - c) The class may not have any 'tos=' options (including - 'tcp-ack'). - - The 'RATE' and 'CEIL' parameters apply to each instance of the - class. So the total RATE represented by an entry with 'occurs' will - be the listed RATE multiplied by the 'occurs' number. - - Example: - - #DEVICE MARK RATE CEIL PRIORITY OPTIONS - 1:100 - 1kbit 230kbit 4 occurs=32d - - The above defines 32 classes. Each class has a guaranteed rate - of 1kbit/second. - - An example of a tcfilter that refers to this class is: - - #INTERFACE: SOURCE DEST PROTO DEST SOURCE - #CLASS PORT(S) PORT(S) - 1:100 - 192.168.1.0/27 - - Traffic destined for each of the 32 addresses in 192.168.1.0/27 - will be directed to a separate class. - - Filters that refer to an occuring class may not specify a PROTO or - PORT(S). - - Note that this feature is not applicable to output traffic where - SNAT is being used because all outgoing packets have the same - SOURCE IP address. - -3) In the 'shorewall compile' command, the filename '-' now causes +2) In the 'shorewall compile' command, the filename '-' is now causes the compiled script to be written to Standard Out. As a side effect, the effective VERBOSITY is set to -1 (silent). @@ -204,7 +144,7 @@ None. issued by /sbin/shorewall (/sbin/shorewall6) when a compilation begins. -4) Supplying an interface name in the SOURCE column of +3) Supplying an interface name in the SOURCE column of /etc/shorewall/masq is now deprecated. Entering the name of an interface there will result in a compile-time warning. @@ -527,3 +467,101 @@ None. In other words, the utilities will be located via the current PATH setting. +16) There has been a desire in the user community to limit traffic by + IP address using Shorewall traffic shaping. Heretofore, that has + required a very inefficient process: + + a) Define a tcclass for each internal host (two, if shaping both in + and out). + b) Define a tcrule for each host to mark to classify the packets + accordingly. + + Beginning with Shorewall 4.3.9, this process is made easier IF YOU + ARE WILLING TO INSTALL xtables-addons. The feature requires IPMARK + support in iptables[6] and your kernel. That support is available + in xtables-addons. + + The new facility has two components: + + a) A new IPMARK MARKing command in /etc/shorewall/tcrules. + b) A new 'occurs' OPTION in /etc/shorewall/tcclasses. + + The IPMARK target assigns a mark to each matching packet based on + the either the source or destination IP address. By default, it + assigns a mark value equal to the low-order 8 bits of the source + address. + + The syntax is as follows: + + IPMARK[([{src|dst}][,[][,[][,[]]]])] + + Default values are: + + src + = 0xFF + = 0x00 + = 0 + + 'src' and 'dst' specify whether the mark is to be based on the + source or destination address respectively. + + The selected address is first LANDed with then LORed with + . + + The result is then shifted bits to the right. + + Example: + + IPMARK(dst, 0XFF00, 0x8000,8) + + Destination IP address is 192.168.4.3 = 0xc0a80403 + + 0xc0a80403 LAND 0xFF00 = 0x0400 + 0x0400 LOR 0x80 = 0x8400 + 0x8400 >> 8 = 0x84 + + Mark = 0x84 = 132 + + The 'occurs' option causes the class definition to be replicated + many times. The synax is: + + occurs= + + When 'occurs' is used: + + a) The associated device may not have the 'classify' option. + b) The class may not be the default class. + c) The class may not have any 'tos=' options (including + 'tcp-ack'). + + The 'RATE' and 'CEIL' parameters apply to each instance of the + class. So the total RATE represented by an entry with 'occurs' will + be the listed RATE multiplied by the 'occurs' number. + + Example: + + #DEVICE MARK RATE CEIL PRIORITY OPTIONS + eth0 100 1kbit 230kbit 4 occurs=32 + + The above defines 32 classes with MARK values 100-131. Each + class has a guaranteed rate of 1kbit/second. + + As part of this change, the generation of class ids from mark + values has been changed. The class number is now + + ( << 10 ) | + + /sbin/shorewall has an 'encode' and 'decode' command to translate a + device number, mark pair to/from a classid: + + encode + decode + + Example: + + $ shorewall decode 3172 + Device = 3 Mark = 100 + $ shorewall encode 3 100 + Class number = 3172 + $ + diff --git a/docs/traffic_shaping.xml b/docs/traffic_shaping.xml index e80a45564..9c04741e8 100644 --- a/docs/traffic_shaping.xml +++ b/docs/traffic_shaping.xml @@ -522,44 +522,6 @@ ppp0 6000kbit 500kbit role="bold">class per interface. - - - occurs=<number>[d|s] - Causes the class definition - to be replicated for a total of number - rules. Each occurance has a successively higher class - number. - - When 'occurs' is used: - - - - The associated device must have the 'classify' - option. - - - - The class may not be the default class. - - - - The class may not have any 'tos=' options (including - 'tcp-ack'). - - - - The 'RATE' and 'CEIL' parameters apply to each instance of - the class. So the total RATE represented by an entry with - 'occurs' will be the listed RATE multiplied by - number. - - The d and s options are used to specify whether the - instances of the class will be assigned by DESTINATION IP - address (d) or SOURCE IP - address (s). The default is - d. See the tcfilters (5). - diff --git a/manpages/shorewall-tcclasses.xml b/manpages/shorewall-tcclasses.xml index a3ffe3237..31abf0163 100644 --- a/manpages/shorewall-tcclasses.xml +++ b/manpages/shorewall-tcclasses.xml @@ -291,20 +291,19 @@ occurs=number[d|s] + role="bold">occurs=number - Causes the class definition to be replicated for a total - of number rules. Each occurance has a - successively higher class number. + Typically used with an IPMARK entry in tcrules. Causes + the rule to be replicated for a total of + number rules. Each rule has a + successively class number and mark value. - When 'occurs' is used: + When 'occurs' is used: - The associated device must have the 'classify' + The associated device may not have the 'classify' option. @@ -321,15 +320,7 @@ The 'RATE' and 'CEIL' parameters apply to each instance of the class. So the total RATE represented by an entry with 'occurs' will be the listed RATE multiplied by - number. - - The d and s options are used to specify whether - the instances of the class will be assigned by DESTINATION IP - address (d) or SOURCE IP - address (s). The default is - d. See the tcfilters (5). + number. diff --git a/manpages/shorewall-tcfilters.xml b/manpages/shorewall-tcfilters.xml index 5ed58eed5..461e8f0c4 100644 --- a/manpages/shorewall-tcfilters.xml +++ b/manpages/shorewall-tcfilters.xml @@ -1,6 +1,4 @@ - shorewall-tcfilters @@ -40,11 +38,7 @@ url="shorewall-tcdevices.html">shorewall-tcdevices(5) followed by a class number defined for that interface in shorewall-tcclasses(5). If - the class is defined with the option then - the filter will use the low-order byte of the SOURCE or DESTINATION - IP address to assign traffic to individual occurances of the - class. + url="shorewall-tcclasses.html">shorewall-tcclasses(5). @@ -85,8 +79,7 @@ role="bold">all} - Protocol. May not be specified in CLASS has the - option. + Protocol. @@ -99,8 +92,7 @@ Destination Ports. A Port name (from services(5)) or a port number; if the protocol is icmp, this column is interpreted as the - destination icmp-type(s). Requires that the PROTO be tcp, udp or - sctp. + destination icmp-type(s). @@ -110,8 +102,7 @@ role="bold">-|port-name-or-number] - Source port. Requires that the PROTO be tcp, udp or - sctp. + Source port. @@ -148,6 +139,12 @@ http://shorewall.net/traffic_shaping.htm + http://shorewall.net/MultiISP.html + + http://shorewall.net/PacketMarking.html + shorewall(8), shorewall-accounting(5), shorewall-actions(5), shorewall-blacklist(5), shorewall-ecn(5), shorewall-exclusion(5), shorewall-hosts(5), shorewall-interfaces(5), shorewall-ipsec(5), @@ -158,4 +155,4 @@ shorewall-tcclasses(5), shorewall-tcdevices(5), shorewall-tos(5), shorewall-tunnels(5), shorewall-zones(5) - + \ No newline at end of file diff --git a/manpages/shorewall-tcrules.xml b/manpages/shorewall-tcrules.xml index 8d851c153..f9bdad456 100644 --- a/manpages/shorewall-tcrules.xml +++ b/manpages/shorewall-tcrules.xml @@ -51,7 +51,10 @@ role="bold">/mask]|CONTINUE|SAME|COMMENT}[COMMENT|IPMARK[([(src|dst}][,[mask1][,[mask2][,[shift]]]]])]}[:{C|F|P|T|CF| To stop the comment from being attached to further rules, simply include COMMENT on a line by itself. + + + IPMARK ‒ Assigns a mark + to each matching packet based on the either the source or + destination IP address. By default, it assigns a mark value + equal to the low-order 8 bits of the source address. Default + values are: + + + src + + mask1 = 0xFF + + mask2 = 0x00 + + shift = 0 + + + 'src' and 'dst' specify whether the mark is to be based on + the source or destination address respectively. The selected + address is first LANDed with mask1 then + LORed with mask2. The + result is then shifted shift bits to the + right. + + Example: + +
+ + IPMARK(dst, 0XFF00, 0x8000,8) + + Destination IP address is 192.168.4.3 = + 0xc0a80103 + Meaning: + + + 0xc0a80403 LAND 0xFF00 = 0x0400 + + 0x0400 LOR 0x80 = 0x8400 + + 0x8400 >> 8 = 0x84 + + Mark = 0x84 = 132 + +
+
diff --git a/manpages6/shorewall6-tcrules.xml b/manpages6/shorewall6-tcrules.xml index f0b894e69..a050981bd 100644 --- a/manpages6/shorewall6-tcrules.xml +++ b/manpages6/shorewall6-tcrules.xml @@ -50,7 +50,10 @@ role="bold">SAVE
[/mask]|CONTINUE|COMMENT}[COMMENT|IPMARK[([(src|dst}][,[mask1][,[mask2][,[shift]]]]])]}[:{C|F|P|T|CF|To stop the comment from being attached to further rules, simply include COMMENT on a line by itself. + + + IPMARK ‒ Assigns a mark + to each matching packet based on the either the source or + destination IP address. By default, it assigns a mark value + equal to the low-order 8 bits of the source address. Default + values are: + + + src + + mask1 = 0xFF + + mask2 = 0x00 + + shift = 0 + + + 'src' and 'dst' specify whether the mark is to be based on + the source or destination address respectively. The selected + address is first LANDed with mask1 then + LORed with mask2. The + result is then shifted shift bits to the + right. + + Example: + +
+ + IPMARK(dst, 0XFF00, 0x8000,8) + + Destination IP address is 192.168.4.3 = + 0xc0a80103 + Meaning: + + + 0xc0a80403 LAND 0xFF00 = 0x0400 + + 0x0400 LOR 0x80 = 0x8400 + + 0x8400 >> 8 = 0x84 + + Mark = 0x84 = 132 + +
+