Improve the efficiency of tcrule processing.

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2012-11-13 06:55:35 -08:00
parent 32c9e4274f
commit 3c58d2180d

View File

@ -215,7 +215,7 @@ sub process_tc_rule( ) {
split_line1 'tcrules file', { mark => 0, action => 0, source => 1, dest => 2, proto => 3, dport => 4, sport => 5, user => 6, test => 7, length => 8, tos => 9, connbytes => 10, helper => 11, headers => 12, probability => 13 , dscp => 14 , state => 15 }, { COMMENT => 0, FORMAT => 2 }, 16; split_line1 'tcrules file', { mark => 0, action => 0, source => 1, dest => 2, proto => 3, dport => 4, sport => 5, user => 6, test => 7, length => 8, tos => 9, connbytes => 10, helper => 11, headers => 12, probability => 13 , dscp => 14 , state => 15 }, { COMMENT => 0, FORMAT => 2 }, 16;
} }
our @tccmd; our %tccmd;
our $format; our $format;
@ -514,7 +514,7 @@ sub process_tc_rule( ) {
} else { } else {
unless ( $classid ) { unless ( $classid ) {
fatal_error "Invalid MARK ($originalmark)" unless $mark =~ /^([0-9a-fA-F]+)$/ and $designator =~ /^([0-9a-fA-F]+)$/; fatal_error "Invalid ACTION ($originalmark)" unless $mark =~ /^([0-9a-fA-F]+)$/ and $designator =~ /^([0-9a-fA-F]+)$/;
fatal_error 'A CLASSIFY rule may not have $FW as the DEST' if $chain eq 'tcin'; fatal_error 'A CLASSIFY rule may not have $FW as the DEST' if $chain eq 'tcin';
$chain = 'tcpost'; $chain = 'tcpost';
$mark = $originalmark; $mark = $originalmark;
@ -552,10 +552,10 @@ sub process_tc_rule( ) {
$list = ''; $list = '';
unless ( $classid ) { unless ( $classid ) {
MARK:
{ {
for my $tccmd ( @tccmd ) { if ( $cmd =~ /^([[A-Z!&]+)/ ) {
if ( $tccmd->{match}($cmd) ) { if ( my $tccmd = $tccmd{$1} ) {
fatal_error "Invalid $1 ACTION ($originalmark)" unless $tccmd->{match}($cmd);
fatal_error "$mark not valid with :C[FPT]" if $connmark; fatal_error "$mark not valid with :C[FPT]" if $connmark;
require_capability ('CONNMARK' , "SAVE/RESTORE Rules", '' ) if $tccmd->{connmark}; require_capability ('CONNMARK' , "SAVE/RESTORE Rules", '' ) if $tccmd->{connmark};
@ -574,7 +574,7 @@ sub process_tc_rule( ) {
} }
if ( $rest ) { if ( $rest ) {
fatal_error "Invalid MARK ($originalmark)" if $marktype == NOMARK; fatal_error "Invalid COMMAND ($originalmark)" if $marktype == NOMARK;
$mark = $rest if $tccmd->{mask}; $mark = $rest if $tccmd->{mask};
@ -586,12 +586,10 @@ sub process_tc_rule( ) {
} elsif ( $tccmd->{mask} ) { } elsif ( $tccmd->{mask} ) {
$mark = $tccmd->{mask}; $mark = $tccmd->{mask};
} }
} else {
last MARK; fatal_error "Invalid ACTION ($originalmark)";
} }
} } elsif ( $mark =~ /-/ ) {
if ( $mark =~ /-/ ) {
( $mark, $mark1 ) = split /-/, $mark, 2; ( $mark, $mark1 ) = split /-/, $mark, 2;
validate_mark $mark; validate_mark $mark;
fatal_error "Invalid mark range ($mark-$mark1)" if $mark =~ m'/'; fatal_error "Invalid mark range ($mark-$mark1)" if $mark =~ m'/';
@ -2318,92 +2316,95 @@ sub setup_tc() {
} }
if ( $config{MANGLE_ENABLED} ) { if ( $config{MANGLE_ENABLED} ) {
our @tccmd = ( { match => sub ( $ ) { $_[0] eq 'SAVE' } , our %tccmd = ( SAVE => { match => sub ( $ ) { $_[0] eq 'SAVE' } ,
target => 'CONNMARK --save-mark --mask' , target => 'CONNMARK --save-mark --mask' ,
mark => $config{TC_EXPERT} ? HIGHMARK : SMALLMARK, mark => $config{TC_EXPERT} ? HIGHMARK : SMALLMARK,
mask => in_hex( $globals{TC_MASK} ) , mask => in_hex( $globals{TC_MASK} ) ,
connmark => 1 connmark => 1
} , } ,
{ match => sub ( $ ) { $_[0] eq 'RESTORE' }, RESTORE => { match => sub ( $ ) { $_[0] eq 'RESTORE' },
target => 'CONNMARK --restore-mark --mask' , target => 'CONNMARK --restore-mark --mask' ,
mark => $config{TC_EXPERT} ? HIGHMARK : SMALLMARK , mark => $config{TC_EXPERT} ? HIGHMARK : SMALLMARK ,
mask => in_hex( $globals{TC_MASK} ) , mask => in_hex( $globals{TC_MASK} ) ,
connmark => 1 connmark => 1
} , } ,
{ match => sub ( $ ) { $_[0] eq 'CONTINUE' }, CONTINUE => { match => sub ( $ ) { $_[0] eq 'CONTINUE' },
target => 'RETURN' , target => 'RETURN' ,
mark => NOMARK , mark => NOMARK ,
mask => '' , mask => '' ,
connmark => 0 connmark => 0
} , } ,
{ match => sub ( $ ) { $_[0] eq 'SAME' }, SAME => { match => sub ( $ ) { $_[0] eq 'SAME' },
target => 'sticky' , target => 'sticky' ,
mark => NOMARK , mark => NOMARK ,
mask => '' , mask => '' ,
connmark => 0 connmark => 0
} , } ,
{ match => sub ( $ ) { $_[0] =~ /^IPMARK/ }, IPMARK => { match => sub ( $ ) { $_[0] =~ /^IPMARK/ },
target => 'IPMARK' , target => 'IPMARK' ,
mark => NOMARK, mark => NOMARK,
mask => '', mask => '',
connmark => 0 connmark => 0
} , } ,
{ match => sub ( $ ) { $_[0] =~ '\|.*'} , '|' => { match => sub ( $ ) { $_[0] =~ '\|.*'} ,
target => 'MARK --or-mark' , target => 'MARK --or-mark' ,
mark => HIGHMARK , mark => HIGHMARK ,
mask => '' } , mask => ''
{ match => sub ( $ ) { $_[0] =~ '&.*' }, } ,
target => 'MARK --and-mark' , '&' => { match => sub ( $ ) { $_[0] =~ '&.*' },
mark => HIGHMARK , target => 'MARK --and-mark' ,
mask => '' , mark => HIGHMARK ,
connmark => 0 mask => '' ,
} , connmark => 0
{ match => sub ( $ ) { $_[0] =~ /^TPROXY/ }, } ,
target => 'TPROXY', TPROXY => { match => sub ( $ ) { $_[0] =~ /^TPROXY/ },
mark => HIGHMARK, target => 'TPROXY',
mask => '', mark => HIGHMARK,
connmark => '' }, mask => '',
{ match => sub( $ ) { $_[0] =~ /^DIVERT/ }, connmark => ''
target => 'DIVERT', },
mark => HIGHMARK, DIVERT => { match => sub( $ ) { $_[0] =~ /^DIVERT/ },
mask => '', target => 'DIVERT',
connmark => '' }, mark => HIGHMARK,
{ match => sub( $ ) { $_[0] =~ /^TTL/ }, mask => '',
target => 'TTL', connmark => ''
mark => NOMARK, },
mask => '', TTL => { match => sub( $ ) { $_[0] =~ /^TTL/ },
connmark => 0 target => 'TTL',
}, mark => NOMARK,
{ match => sub( $ ) { $_[0] =~ /^HL/ }, mask => '',
target => 'HL', connmark => 0
mark => NOMARK, },
mask => '', HL => { match => sub( $ ) { $_[0] =~ /^HL/ },
connmark => 0 target => 'HL',
}, mark => NOMARK,
{ match => sub( $ ) { $_[0] =~ /^IMQ\(\d+\)$/ }, mask => '',
target => 'IMQ', connmark => 0
mark => NOMARK, },
mask => '', IMQ => { match => sub( $ ) { $_[0] =~ /^IMQ\(\d+\)$/ },
connmark => 0 target => 'IMQ',
}, mark => NOMARK,
{ match => sub( $ ) { $_[0] =~ /^DSCP\(\w+\)$/ }, mask => '',
target => 'DSCP', connmark => 0
mark => NOMARK, },
mask => '', DSCP => { match => sub( $ ) { $_[0] =~ /^DSCP\(\w+\)$/ },
connmark => 0 target => 'DSCP',
}, mark => NOMARK,
{ match => sub( $ ) { $_[0] =~ /^TOS\(.+\)$/ }, mask => '',
target => 'TOS', connmark => 0
mark => NOMARK, },
mask => '', TOS => { match => sub( $ ) { $_[0] =~ /^TOS\(.+\)$/ },
connmark => 0 target => 'TOS',
}, mark => NOMARK,
{ match => sub( $ ) { $_[0] eq 'CHECKSUM' }, mask => '',
target => 'CHECKSUM' , connmark => 0
mark => NOMARK, },
mask => '', CHECKSUM => { match => sub( $ ) { $_[0] eq 'CHECKSUM' },
connmark => 0, target => 'CHECKSUM' ,
} mark => NOMARK,
mask => '',
connmark => 0,
}
); );
if ( my $fn = open_file 'tcrules' ) { if ( my $fn = open_file 'tcrules' ) {