Port Simplified TC to 4.4.6

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2010-01-12 17:01:20 -08:00
parent 7e183e8eb4
commit f69a741691
4 changed files with 217 additions and 8 deletions

View File

@ -227,6 +227,7 @@ our %capdesc = ( NAT_ENABLED => 'NAT',
KLUDGEFREE => 'Repeat match',
MARK => 'MARK Target',
XMARK => 'Extended Mark Target',
EXMARK => 'Extended Mark Target 2',
MANGLE_FORWARD => 'Mangle FORWARD Chain',
COMMENTS => 'Comments',
ADDRTYPE => 'Address Type Match',
@ -330,7 +331,7 @@ sub initialize( $ ) {
EXPORT => 0,
UNTRACKED => 0,
VERSION => "4.4.6-Beta1",
CAPVERSION => 40406 ,
CAPVERSION => 40407 ,
);
#
@ -403,6 +404,7 @@ sub initialize( $ ) {
RETAIN_ALIASES => undef,
TC_ENABLED => undef,
TC_EXPERT => undef,
TC_PRIOMAP => undef,
CLEAR_TC => undef,
MARK_IN_FORWARD_CHAIN => undef,
CLAMPMSS => undef,
@ -534,6 +536,7 @@ sub initialize( $ ) {
IP_FORWARDING => undef,
TC_ENABLED => undef,
TC_EXPERT => undef,
TC_PRIOMAP => undef,
CLEAR_TC => undef,
MARK_IN_FORWARD_CHAIN => undef,
CLAMPMSS => undef,
@ -619,6 +622,7 @@ sub initialize( $ ) {
KLUDGEFREE => undef,
MARK => undef,
XMARK => undef,
EXMARK => undef,
MANGLE_FORWARD => undef,
COMMENTS => undef,
ADDRTYPE => undef,
@ -2122,6 +2126,7 @@ sub determine_capabilities( $ ) {
if ( qt1( "$iptables -t mangle -A $sillyname -j MARK --set-mark 1" ) ) {
$capabilities{MARK} = 1;
$capabilities{XMARK} = qt1( "$iptables -t mangle -A $sillyname -j MARK --and-mark 0xFF" );
$capabilities{EXMARK} = qt1( "$iptables -t mangle -A $sillyname -j MARK --set-mark 1/0xFF" );
}
if ( qt1( "$iptables -t mangle -A $sillyname -j CONNMARK --save-mark" ) ) {
@ -2590,6 +2595,8 @@ sub get_configuration( $ ) {
$globals{TC_SCRIPT} = $file;
} elsif ( $val eq 'internal' ) {
$config{TC_ENABLED} = 'Internal';
} elsif ( $val eq 'simple' ) {
$config{TC_ENABLED} = 'Simple';
} else {
fatal_error "Invalid value ($config{TC_ENABLED}) for TC_ENABLED" unless $val eq 'no';
$config{TC_ENABLED} = '';
@ -2600,6 +2607,19 @@ sub get_configuration( $ ) {
require_capability 'MANGLE_ENABLED', "TC_ENABLED=$config{TC_ENABLED}", 's';
}
if ( $val = $config{TC_PRIOMAP} ) {
my @priomap = split ' ',$val;
fatal_error "Invalid TC_PRIOMAP ($val)" unless @priomap == 16;
for ( @priomap ) {
fatal_error "Invalid TC_PRIOMAP entry ($_)" unless /[1-3]/;
$_--;
}
$config{TC_PRIOMAP} = join ' ', @priomap;
} else {
$config{TC_PRIOMAP} = '1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1';
}
default 'RESTOREFILE' , 'restore';
default 'IPSECFILE' , 'zones';
default 'DROP_DEFAULT' , 'Drop';

View File

@ -130,6 +130,7 @@ our %tcdevices;
our @devnums;
our $devnum;
our $sticky;
our $ipp2p;
#
@ -183,6 +184,7 @@ sub initialize( $ ) {
@devnums = ();
$devnum = 0;
$sticky = 0;
$ipp2p = 0;
}
sub process_tc_rule( ) {
@ -409,6 +411,96 @@ sub process_flow($) {
$flow;
}
sub process_simple_device() {
my ( $device , $type , $bandwidth ) = split_line 1, 3, 'tcinterfaces';
my $devnumber;
if ( $device =~ /:/ ) {
( my $number, $device, my $rest ) = split /:/, $device, 3;
fatal_error "Invalid NUMBER:INTERFACE ($device:$number:$rest)" if defined $rest;
if ( defined $number ) {
$devnumber = hex_value( $number );
fatal_error "Invalid interface NUMBER ($number)" unless defined $devnumber && $devnumber;
fatal_error "Duplicate interface number ($number)" if defined $devnums[ $devnumber ];
$devnum = $devnumber if $devnumber > $devnum;
} else {
fatal_error "Missing interface NUMBER";
}
} else {
$devnumber = ++$devnum;
}
$devnums[ $devnumber ] = $device;
my $number = in_hexp $devnumber;
fatal_error "Duplicate INTERFACE ($device)" if $tcdevices{$device};
fatal_error "Invalid INTERFACE name ($device)" if $device =~ /[:+]/;
my $physical = physical_name $device;
my $dev = chain_base( $physical );
if ( $type ne '-' ) {
if ( lc $type eq 'external' ) {
$type = 'nfct-src';
} elsif ( lc $type eq 'internal' ) {
$type = 'dst';
} else {
fatal_error "Invalid TYPE ($type)";
}
}
$tcdevices{$device} = { number => $devnumber ,
physical => physical_name $device ,
type => $type ,
in_bandwidth => $bandwidth = rate_to_kbit( $bandwidth ) ,
};
push @tcdevices, $device;
emit "if interface_is_up $physical; then";
push_indent;
emit ( "${dev}_exists=Yes",
"qt \$TC qdisc del dev $physical root",
"qt \$TC qdisc del dev $physical ingress\n"
);
if ( $bandwidth ) {
emit ( "run_tc qdisc add dev $physical handle ffff: ingress",
"run_tc filter add dev $physical parent ffff: protocol all prio 10 u32 match ip src 0.0.0.0/0 police rate ${bandwidth}kbit burst 10k drop flowid :1\n"
);
}
emit "run_tc qdisc add dev $physical root handle $number: prio bands 3 priomap $config{TC_PRIOMAP}";
my $i = 0;
while ( ++$i <= 3 ) {
emit "run_tc qdisc add dev $physical parent $number:$i handle ${number}${i}: sfq quantum 1500 limit 127 perturb 10";
emit "run_tc filter add dev $physical protocol all parent $number: handle $i fw classid $devnum:$i";
emit "run_tc filter add dev $physical protocol all prio 1 parent ${number}$i: handle ${number}${i} flow hash keys $type divisor 1024" if $type ne '-';
emit '';
}
save_progress_message_short " TC Device $physical defined.";
pop_indent;
emit 'else';
push_indent;
emit qq(error_message "WARNING: Device $physical is not in the UP state -- traffic-shaping configuration skipped");
emit "${dev}_exists=";
pop_indent;
emit "fi\n";
progress_message " Simple tcdevice \"$currentline\" $done.";
}
sub validate_tc_device( ) {
my ( $device, $inband, $outband , $options , $redirected ) = split_line 3, 5, 'tcdevices';
@ -976,6 +1068,91 @@ sub process_tc_filter( ) {
}
sub process_tc_priority() {
my ( $band, $proto, $ports , $address, $interface, $helper ) = split_line1 1, 6, 'tcpri';
if ( $band eq 'COMMENT' ) {
process_comment;
return;
}
my $val = numeric_value $band;
fatal_error "Invalid PRIORITY ($band)" unless $val && $val <= 3;
my $rule = do_helper( $helper ) . "-j MARK --set-mark $band";
$rule .= join('', '/', in_hex( $globals{TC_MASK} ) ) if $capabilities{EXMARK};
if ( $interface ne '-' ) {
fatal_error "Invalid combination of columns" unless $address eq '-' && $proto eq '-' && $ports eq '-';
my $forwardref = $mangle_table->{tcfor};
add_rule( $forwardref ,
join( '', match_source_dev( $interface) , $rule ) ,
1 );
} else {
my $postref = $mangle_table->{tcpost};
if ( $address ne '-' ) {
fatal_error "Invalid combination of columns" unless $proto eq '-' && $ports eq '-';
add_rule( $postref ,
join( '', match_source_net( $address) , $rule ) ,
1 );
} else {
add_rule( $postref ,
join( '', do_proto( $proto, $ports, '-' , 0 ) , $rule ) ,
1 );
if ( $ports ne '-' ) {
my $protocol = resolve_proto $proto;
if ( $proto =~ /^ipp2p/ ) {
fatal_error "ipp2p may not be used when there are tracked providers and PROVIDER_OFFSET=0" if @routemarked_interfaces && $config{PROVIDER_OFFSET} == 0;
$ipp2p = 1;
}
add_rule( $postref ,
join( '' , do_proto( $proto, '-', $ports, 0 ) , $rule ) ,
1 )
unless $proto =~ /^ipp2p/ || $protocol == ICMP || $protocol == IPv6_ICMP;
}
}
}
}
sub setup_simple_traffic_shaping() {
my $interfaces;
save_progress_message "Setting up Traffic Control...";
my $fn = open_file 'tcinterfaces';
if ( $fn ) {
first_entry "$doing $fn...";
process_simple_device, $interfaces++ while read_a_line;
} else {
$fn = find_file 'tcinterfaces';
}
my $fn1 = open_file 'tcpri';
if ( $fn1 ) {
first_entry sub { progress_message2 "$doing $fn1...";
warning_message "There are entries in $fn1 but $fn was empty" unless $interfaces;
};
process_tc_priority while read_a_line;
clear_comment;
if ( $ipp2p ) {
insert_rule1 $mangle_table->{tcpost} , 0 , '-m mark --mark 0/' . in_hex( $globals{TC_MASK} ) . ' -j CONNMARK --restore-mark --ctmask ' . in_hex( $globals{TC_MASK} );
add_rule $mangle_table->{tcpost} , '-m mark ! --mark 0/' . in_hex( $globals{TC_MASK} ) . ' -j CONNMARK --save-mark --ctmask ' . in_hex( $globals{TC_MASK} );
}
}
}
sub setup_traffic_shaping() {
our $lastrule = '';
@ -1185,8 +1362,10 @@ sub setup_tc() {
if ( @routemarked_interfaces && ! $config{TC_EXPERT} ) {
$mark_part = '-m mark --mark 0/' . in_hex( $globals{PROVIDER_MASK} ) . ' ';
for my $interface ( @routemarked_interfaces ) {
add_rule $mangle_table->{PREROUTING} , match_source_dev( $interface ) . "-j tcpre";
unless ( $config{TRACK_PROVIDERS} ) {
for my $interface ( @routemarked_interfaces ) {
add_rule $mangle_table->{PREROUTING} , match_source_dev( $interface ) . "-j tcpre";
}
}
}
@ -1205,6 +1384,8 @@ sub setup_tc() {
append_file $globals{TC_SCRIPT};
} elsif ( $config{TC_ENABLED} eq 'Internal' ) {
setup_traffic_shaping;
} elsif ( $config{TC_ENABLED} eq 'Simple' ) {
setup_simple_traffic_shaping;
}
if ( $config{TC_ENABLED} ) {

View File

@ -4,7 +4,7 @@
#
# This program is under GPL [http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt]
#
# (c) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 - Tom Eastep (teastep@shorewall.net)
# (c) 1999,2000,2001,2002,2003,2004,2005,2006,2007 - Tom Eastep (teastep@shorewall.net)
#
# Complete documentation is available at http://shorewall.net
#
@ -30,7 +30,7 @@
#
SHOREWALL_LIBVERSION=40406
SHOREWALL_CAPVERSION=40406
SHOREWALL_CAPVERSION=40407
[ -n "${VARDIR:=/var/lib/shorewall}" ]
[ -n "${SHAREDIR:=/usr/share/shorewall}" ]
@ -813,6 +813,7 @@ determine_capabilities() {
KLUDGEFREE=
MARK=
XMARK=
EXMARK=
MANGLE_FORWARD=
COMMENTS=
ADDRTYPE=
@ -914,6 +915,7 @@ determine_capabilities() {
if qt $IPTABLES -t mangle -A $chain -j MARK --set-mark 1; then
MARK=Yes
qt $IPTABLES -t mangle -A $chain -j MARK --and-mark 0xFF && XMARK=Yes
qt $IPTABLES -t mangle -A $chain -j MARK --set-mark 1/0xFF && EXMARK=Yes
fi
if qt $IPTABLES -t mangle -A $chain -j CONNMARK --save-mark; then
@ -1011,6 +1013,7 @@ report_capabilities() {
report_capability "Repeat match" $KLUDGEFREE
report_capability "MARK Target" $MARK
[ -n "$MARK" ] && report_capability "Extended MARK Target" $XMARK
[ -n "$XMARK" ] && report_capability "Extended MARK Target 2" $EXMARK
report_capability "Mangle FORWARD Chain" $MANGLE_FORWARD
report_capability "Comments" $COMMENTS
report_capability "Address Type Match" $ADDRTYPE
@ -1070,6 +1073,7 @@ report_capabilities1() {
report_capability1 KLUDGEFREE
report_capability1 MARK
report_capability1 XMARK
report_capability1 EXMARK
report_capability1 MANGLE_FORWARD
report_capability1 COMMENTS
report_capability1 ADDRTYPE

View File

@ -4,7 +4,7 @@
#
# This program is under GPL [http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt]
#
# (c) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 - Tom Eastep (teastep@shorewall.net)
# (c) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 - Tom Eastep (teastep@shorewall.net)
#
# Complete documentation is available at http://shorewall.net
#
@ -33,7 +33,7 @@
#
SHOREWALL_LIBVERSION=40406
SHOREWALL_CAPVERSION=40406
SHOREWALL_CAPVERSION=40407
[ -n "${VARDIR:=/var/lib/shorewall6}" ]
[ -n "${SHAREDIR:=/usr/share/shorewall6}" ]
@ -722,6 +722,7 @@ determine_capabilities() {
KLUDGEFREE=
MARK=
XMARK=
EXMARK=
MANGLE_FORWARD=
COMMENTS=
ADDRTYPE=
@ -746,7 +747,7 @@ determine_capabilities() {
fi
qt $IP6TABLES -t mangle -L -n && MANGLE_ENABLED=Yes || MANGLE_ENABLED=
qt $IP6TABLES -F $chain
qt $IP6TABLES -X $chain
if ! $IP6TABLES -N $chain; then
@ -822,6 +823,7 @@ determine_capabilities() {
if qt $IP6TABLES -t mangle -A $chain -j MARK --set-mark 1; then
MARK=Yes
qt $IP6TABLES -t mangle -A $chain -j MARK --and-mark 0xFF && XMARK=Yes
qt $IP6TABLES -t mangle -A $chain -j MARK --set-mark 1/0xFF && EXMARK=Yes
fi
if qt $IP6TABLES -t mangle -A $chain -j CONNMARK --save-mark; then
@ -917,6 +919,7 @@ report_capabilities() {
report_capability "Repeat match" $KLUDGEFREE
report_capability "MARK Target" $MARK
[ -n "$MARK" ] && report_capability "Extended MARK Target" $XMARK
[ -n "$XMARK" ] && report_capability "Extended MARK Target 2" $EXMARK
report_capability "Mangle FORWARD Chain" $MANGLE_FORWARD
report_capability "Comments" $COMMENTS
report_capability "Address Type Match" $ADDRTYPE
@ -973,6 +976,7 @@ report_capabilities1() {
report_capability1 KLUDGEFREE
report_capability1 MARK
report_capability1 XMARK
report_capability1 EXMARK
report_capability1 MANGLE_FORWARD
report_capability1 COMMENTS
report_capability1 ADDRTYPE