Correct defects found during testing of ematch.

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2014-01-21 12:53:33 -08:00
parent 9c4089fc99
commit 62557cb98e
2 changed files with 29 additions and 28 deletions

View File

@ -311,18 +311,18 @@ sub decompose_net( $ ) {
# For example, a /64 network will return two pairs; a /80 would return 3. # For example, a /64 network will return two pairs; a /80 would return 3.
# #
sub decompose_net_u32( $ ) { sub decompose_net_u32( $ ) {
my ( $net, $vlsm ) = decompose_net( $_[0] ); my ( $net, $vlsm ) = validate_net( $_[0] , 0 );
assert( wantarray ); assert( wantarray );
if ( $family == F_IPV4 ) { if ( $family == F_IPV4 ) {
$vlsm = ( 0xffffffff << ( $vlsm-32 ) ) & 0xffffffff; $vlsm = ( 0xffffffff << ( 32 - $vlsm ) ) & 0xffffffff;
return ( in_hex8( $vlsm ) , in_hex8( $net ) ); return ( in_hex8( $vlsm ) , in_hex8( $net ) );
} }
# #
# Split the address into 16-bit hex numbers # Split the address into 16-bit hex numbers
# #
my @addr = split( ':', $net ); my @addr = split( ':', normalize_6addr( $net ) );
# #
# Replace each element by its numeric value # Replace each element by its numeric value
# #
@ -339,7 +339,7 @@ sub decompose_net_u32( $ ) {
} }
if ( $vlsm ) { if ( $vlsm ) {
push @result, ( ( 0xffffffff << ( $vlsm-32 ) ) & 0xffffffff ); push @result, ( ( 0xffffffff << ( 32 - $vlsm ) ) & 0xffffffff );
push @result, ( ( $addr[0] << 16) | $addr[1] ); push @result, ( ( $addr[0] << 16) | $addr[1] );
} }

View File

@ -2317,7 +2317,7 @@ sub process_tc_filter2( $$$$$$$$$ ) {
$protonumber = resolve_proto $proto; $protonumber = resolve_proto $proto;
fatal_error "Unknown PROTO ($proto)" unless defined $protonumber; fatal_error "Unknown PROTO ($proto)" unless defined $protonumber;
if ( $protonumber ) { if ( $protonumber ) {
$rule .= 'and ' if $have_rule; $rule .= ' and ' if $have_rule;
$rule .= "\\\n match cmp\\( u8 at 6 mask 0xff eq $protonumber \\)"; $rule .= "\\\n match cmp\\( u8 at 6 mask 0xff eq $protonumber \\)";
$have_rule = 1; $have_rule = 1;
} }
@ -2337,11 +2337,11 @@ sub process_tc_filter2( $$$$$$$$$ ) {
push @sportlist, expand_port_range( $protonumber, $_ ) for split_list( $sportlist, 'port list' ); push @sportlist, expand_port_range( $protonumber, $_ ) for split_list( $sportlist, 'port list' );
$rule .= "\\\n (" if $multiple = ( @sportlist > 1 ); $rule .= "\\\n (" if $multiple = ( @sportlist > 2 );
while ( @sportlist ) { while ( @sportlist ) {
my ( $sport, $smask ) = ( shift @sportlist, shift @sportlist ); my ( $sport, $smask ) = ( shift @sportlist, shift @sportlist );
$rule .= "\\\n cmp( u16 at 0 layer 2 mask $smask eq $sport \\)"; $rule .= "\\\n cmp\\( u16 at 0 layer 2 mask $smask eq $sport \\)";
$rule .= ' or' if @sportlist; $rule .= ' or' if @sportlist;
} }
@ -2359,9 +2359,9 @@ sub process_tc_filter2( $$$$$$$$$ ) {
$rule .= "\\\n (" if @typelist > 1; $rule .= "\\\n (" if @typelist > 1;
for my $type ( @typelist ) { for my $type ( @typelist ) {
my ( $icmptype , $icmpcode ) = split '/', validate_icmp( $type ); my ( $icmptype , $icmpcode ) = split '/', validate_icmp\\( $type );
$rule .= "\\\n cmp( u16 at 0 layer 2 mask 0xffff eq " . in_hex4( ( $icmptype << 8 ) | $icmpcode ); $rule .= "\\\n cmp\\( u16 at 0 layer 2 mask 0xffff eq " . in_hex4( ( $icmptype << 8 ) | $icmpcode );
$rule .= ' or' if @typelist > 1; $rule .= ' or' if @typelist > 1;
} }
@ -2379,7 +2379,7 @@ sub process_tc_filter2( $$$$$$$$$ ) {
my ( $icmptype , $icmpcode ) = split '/', validate_icmp6( $type ); my ( $icmptype , $icmpcode ) = split '/', validate_icmp6( $type );
$rule .= "\\\n cmp( u16 at 0 layer 2 mask 0xffff eq " . in_hex4( ( $icmptype << 8 ) | $icmpcode ); $rule .= "\\\n cmp\\( u16 at 0 layer 2 mask 0xffff eq " . in_hex4( ( $icmptype << 8 ) | $icmpcode );
$rule .= ' or' if @typelist > 1; $rule .= ' or' if @typelist > 1;
} }
@ -2390,28 +2390,31 @@ sub process_tc_filter2( $$$$$$$$$ ) {
push @portlist, expand_port_range( $protonumber, $_ ) for split_list( $portlist, 'port list' ); push @portlist, expand_port_range( $protonumber, $_ ) for split_list( $portlist, 'port list' );
$rule .= "\\\n (" if $multiple = ( @portlist > 1 ); $rule .= "\\\n (" if $multiple = ( @portlist > 2 );
while ( @portlist ) { while ( @portlist ) {
my ( $port, $mask ) = ( shift @portlist, shift @portlist ); my ( $port, $mask ) = ( shift @portlist, shift @portlist );
$rule .= "\\\n cmp( u16 at 2 layer 2 mask $mask eq $port \\)"; $rule .= "\\\n cmp\\( u16 at 2 layer 2 mask $mask eq $port \\)";
$rule .= ' or' if @portlist; $rule .= ' or' if @portlist;
} }
$rule .= "\\\n \\)" if $multiple; $rule .= "\\\n \\)" if $multiple;
$rule .= ' and';
push @portlist, expand_port_range( $protonumber, $_ ) for split_list( $sportlist, 'port list' ); if ( $sportlist ne '-' ) {
$rule .= ' and';
$rule .= "\\\n (" if $multiple = ( @portlist > 1 ); push @portlist, expand_port_range( $protonumber, $_ ) for split_list( $sportlist, 'port list' );
while ( @portlist ) { $rule .= "\\\n (" if $multiple = ( @portlist > 2 );
my ( $sport, $smask ) = ( shift @portlist, shift @portlist );
$rule .= "\\\n cmp( u16 at 0 layer 2 mask $smask eq $sport \\)"; while ( @portlist ) {
$rule .= ' or' if @portlist; my ( $sport, $smask ) = ( shift @portlist, shift @portlist );
$rule .= "\\\n cmp\\( u16 at 0 layer 2 mask $smask eq $sport \\)";
$rule .= ' or' if @portlist;
}
$rule .= "\\\n \\)" if $multiple;
} }
$rule .= "\\\n \\)" if $multiple;
} }
} }
} }
@ -2425,12 +2428,12 @@ sub process_tc_filter2( $$$$$$$$$ ) {
my @parts = decompose_net_u32( $source ); my @parts = decompose_net_u32( $source );
if ( $family == F_IPV4 ) { if ( $family == F_IPV4 ) {
$rule .= join( ' ', "\\\n cmp\\( u32 at 12 mask ", in_hex8( $parts[0] ), 'eq' , in_hex8( $parts[1] ), "\\)" ); $rule .= join( ' ', "\\\n cmp\\( u32 at 12 mask", $parts[0] , 'eq' , $parts[1], "\\)" );
} else { } else {
my $offset = 8; my $offset = 8;
while ( @parts ) { while ( @parts ) {
$rule .= join( ' ', "\\\n cmp\\( u32 at $offset mask ", in_hex8( shift @parts ) , 'eq' , in_hex8( shift @parts ), "\\)" ); $rule .= join( ' ', "\\\n cmp\\( u32 at $offset mask", shift @parts , 'eq' , shift @parts , "\\)" );
$offset += 4; $offset += 4;
$rule .= ' and' if @parts; $rule .= ' and' if @parts;
} }
@ -2446,17 +2449,15 @@ sub process_tc_filter2( $$$$$$$$$ ) {
if ( $dest =~ /^\+/ ) { if ( $dest =~ /^\+/ ) {
$rule .= join( ' ', "\\\n ", handle_ematch( $dest, 'dst' ) ); $rule .= join( ' ', "\\\n ", handle_ematch( $dest, 'dst' ) );
} else { } else {
$rule .= 'and ' if $have_rule;
my @parts = decompose_net_u32( $dest ); my @parts = decompose_net_u32( $dest );
if ( $family == F_IPV4 ) { if ( $family == F_IPV4 ) {
$rule .= join( ' ', "\\\n cmp\\( u32 at 12 mask ", in_hex8( $parts[0] ), 'eq' , in_hex8( $parts[1] ), "\\)" ); $rule .= join( ' ', "\\\n cmp\\( u32 at 16 mask", $parts[0] , 'eq' , $parts[1] , "\\)" );
} else { } else {
my $offset = 8; my $offset = 24;
while ( @parts ) { while ( @parts ) {
$rule .= join( ' ', "\\\n cmp\\( u32 at $offset", in_hex8( shift @parts ), 'eq' , in_hex8( shift @parts ), "\\)" ); $rule .= join( ' ', "\\\n cmp\\( u32 at $offset mask", shift @parts , 'eq' , shift @parts , "\\)" );
$offset += 4; $offset += 4;
$rule .= ' and' if @parts; $rule .= ' and' if @parts;
} }