From 22da513b3a9bcdd1cef25ced755b5ccce6372779 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sat, 2 May 2009 09:25:27 -0700 Subject: [PATCH] Vastly simplify generation of tc filters Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/IPAddrs.pm | 4 +- Shorewall/Perl/Shorewall/Tc.pm | 67 +++++++++-------------------- 2 files changed, 21 insertions(+), 50 deletions(-) diff --git a/Shorewall/Perl/Shorewall/IPAddrs.pm b/Shorewall/Perl/Shorewall/IPAddrs.pm index c01d9d868..7a24e4464 100644 --- a/Shorewall/Perl/Shorewall/IPAddrs.pm +++ b/Shorewall/Perl/Shorewall/IPAddrs.pm @@ -263,11 +263,9 @@ sub ip_range_explicit( $ ) { sub decompose_net( $ ) { my $net = $_[0]; - return ( qw/0x00000000 0x00000000/ ) if $net eq '-'; - ( $net, my $vlsm ) = validate_net( $net , 0 ); - ( in_hex8( $net ) , vlsm_to_mask( $vlsm ) ); + ( encodeaddr( $net ) , $vlsm ); } diff --git a/Shorewall/Perl/Shorewall/Tc.pm b/Shorewall/Perl/Shorewall/Tc.pm index 02884086d..2f82aa50d 100644 --- a/Shorewall/Perl/Shorewall/Tc.pm +++ b/Shorewall/Perl/Shorewall/Tc.pm @@ -706,19 +706,25 @@ sub process_tc_filter( $$$$$$ ) { fatal_error "No Classes were defined for INTERFACE $device" unless $tcref; - $tcref = $tcref->{$class}; + my $classnum = hex_value $class; + + fatal_error "Invalid CLASS ($class)" unless defined $classnum; + + $tcref = $tcref->{$classnum}; fatal_error "Unknown CLASS ($devclass)" unless $tcref; my $rule = "filter add dev $device protocol ip parent $devnum:0 prio 10 u32"; - my ( $net , $mask ) = decompose_net( $source ); + if ( $source ne '-' ) { + my ( $net , $mask ) = decompose_net( $source ); + $rule .= "\\\n match ip src $net/$mask"; + } - $rule .= "\\\n match u32 $net $mask at 12" unless $mask eq '0x00000000'; - - ( $net , $mask ) = decompose_net( $dest ); - - $rule .= "\\\n match u32 $net $mask at 16" unless $mask eq '0x00000000'; + if ( $dest ne '-' ) { + my ( $net , $mask ) = decompose_net( $dest ); + $rule .= "\\\n match ip dst $net/$mask"; + } my $protonumber = 0; @@ -727,8 +733,7 @@ sub process_tc_filter( $$$$$$ ) { fatal_error "Unknown PROTO ($proto)" unless defined $protonumber; if ( $protonumber ) { - my $pnumber = in_hex2 $protonumber; - $rule .= "\\\n match u8 $pnumber 0xff at 9"; + $rule .= "\\\n match ip protocol $protonumber 0xff"; } } @@ -737,40 +742,8 @@ sub process_tc_filter( $$$$$$ ) { " flowid $devref->{number}:$class" , '' ); } else { - our $lastrule; - our $lasttnum; - # - # In order to be able to access the protocol header, we must create another hash table and link to it. - # - # Create the Table. - # - my $tnum; - - if ( $lastrule eq $rule ) { - # - # The source, dest and protocol are the same as the last rule that specified a port - # Use the same table - # - $tnum = $lasttnum - } else { - $tnum = in_hex3 $devref->{tablenumber}++; - $lasttnum = $tnum; - $lastrule = $rule; - - emit( "\nrun_tc filter add dev $device parent $devnum:0 protocol ip prio 10 handle $tnum: u32 divisor 1" ); - } - # - # And link to it using the current contents of $rule - # - emit( "\nrun_tc $rule\\" , - " link $tnum:0 offset at 0 mask 0x0F00 shift 6 plus 0 eat" ); - # - # The rule to match the port(s) will be inserted into the new table - # - $rule = "filter add dev $device protocol ip parent $devnum:0 prio 10 u32 ht $tnum:0"; - if ( $portlist eq '-' ) { - fatal_error "Only TCP, UDP and SCTP may specify SOURCE PORT" + fatal_error "Only TCPUDP and SCTP may specify SOURCE PORT" unless $protonumber == TCP || $protonumber == UDP || $protonumber == SCTP; for my $sportrange ( split_list $sportlist , 'port list' ) { @@ -779,7 +752,7 @@ sub process_tc_filter( $$$$$$ ) { while ( @sportlist ) { my ( $sport, $smask ) = ( shift @sportlist, shift @sportlist ); emit( "\nrun_tc $rule\\" , - " match u32 0x${sport}0000 0x${smask}0000 at nexthdr+0\\" , + " match ip sport 0x$sport 0x$smask\\", " flowid $devref->{number}:$class" ); } } @@ -796,8 +769,8 @@ sub process_tc_filter( $$$$$$ ) { $icmptype = in_hex2 numeric_value1 $icmptype; $icmpcode = in_hex2 numeric_value1 $icmpcode if defined $icmpcode; - my $rule1 = " match u8 $icmptype 0xff at nexthdr+0"; - $rule1 .= "\\\n match u8 $icmpcode 0xff at nexthdr+1" if defined $icmpcode; + my $rule1 = " match icmp type $icmptype 0xff"; + $rule1 .= "\\\n match icmp code $icmpcode 0xff" if defined $icmpcode; emit( "\nrun_tc ${rule}\\" , "$rule1\\" , " flowid $devref->{number}:$class" ); @@ -807,7 +780,7 @@ sub process_tc_filter( $$$$$$ ) { while ( @portlist ) { my ( $port, $mask ) = ( shift @portlist, shift @portlist ); - my $rule1 = "match u32 0x0000${port} 0x0000${mask} at nexthdr+0"; + my $rule1 = "match ip dport 0x${port} 0x${mask}"; if ( $sportlist eq '-' ) { emit( "\nrun_tc ${rule}\\" , @@ -822,7 +795,7 @@ sub process_tc_filter( $$$$$$ ) { emit( "\nrun_tc ${rule}\\", " $rule1\\" , - " match u32 0x${sport}0000 0x${smask}0000 at nexthdr+0\\" , + " match ip sport 0x$sport 0x$smask\\", " flowid $devref->{number}:$class" ); } }