mirror of
https://gitlab.com/shorewall/code.git
synced 2024-11-23 08:03:11 +01:00
Implement ipset matches in tcfilters
Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
parent
78ecf9bdc8
commit
7e1a310929
@ -374,6 +374,7 @@ our %capdesc = ( NAT_ENABLED => 'NAT',
|
||||
CONDITION_MATCH => 'Condition Match',
|
||||
IPTABLES_S => 'iptables -S',
|
||||
BASIC_FILTER => 'Basic Filter',
|
||||
BASIC_EMATCH => 'Basic Filter ematch',
|
||||
CT_TARGET => 'CT Target',
|
||||
STATISTIC_MATCH =>
|
||||
'Statistics Match',
|
||||
@ -953,6 +954,7 @@ sub initialize( $;$$) {
|
||||
CONDITION_MATCH => undef,
|
||||
IPTABLES_S => undef,
|
||||
BASIC_FILTER => undef,
|
||||
BASIC_EMATCH => undef,
|
||||
CT_TARGET => undef,
|
||||
STATISTIC_MATCH => undef,
|
||||
IMQ_TARGET => undef,
|
||||
@ -4270,6 +4272,10 @@ sub Basic_Filter() {
|
||||
$tc && system( "$tc filter add basic help 2>&1 | grep -q ^Usage" ) == 0;
|
||||
}
|
||||
|
||||
sub Basic_Ematch() {
|
||||
$tc && have_capability 'BASIC_FILTER' && system( "$tc filter add basic help 2>&1 | egrep -q match" ) == 0;
|
||||
}
|
||||
|
||||
sub Fwmark_Rt_Mask() {
|
||||
$ip && system( "$ip rule add help 2>&1 | grep -q /MASK" ) == 0;
|
||||
}
|
||||
@ -4372,6 +4378,7 @@ our %detect_capability =
|
||||
AUDIT_TARGET => \&Audit_Target,
|
||||
ADDRTYPE => \&Addrtype,
|
||||
BASIC_FILTER => \&Basic_Filter,
|
||||
BASIC_EMATCH => \&Basic_Ematch,
|
||||
CHECKSUM_TARGET => \&Checksum_Target,
|
||||
CLASSIFY_TARGET => \&Classify_Target,
|
||||
CONDITION_MATCH => \&Condition_Match,
|
||||
@ -4585,6 +4592,7 @@ sub determine_capabilities() {
|
||||
$capabilities{CONDITION_MATCH} = detect_capability( 'CONDITION_MATCH' );
|
||||
$capabilities{IPTABLES_S} = detect_capability( 'IPTABLES_S' );
|
||||
$capabilities{BASIC_FILTER} = detect_capability( 'BASIC_FILTER' );
|
||||
$capabilities{BASIC_EMATCH} = detect_capability( 'BASIC_EMATCH' );
|
||||
$capabilities{CT_TARGET} = detect_capability( 'CT_TARGET' );
|
||||
$capabilities{STATISTIC_MATCH} = detect_capability( 'STATISTIC_MATCH' );
|
||||
$capabilities{IMQ_TARGET} = detect_capability( 'IMQ_TARGET' );
|
||||
|
@ -1908,6 +1908,36 @@ sub validate_tc_class( ) {
|
||||
|
||||
my %validlengths = ( 32 => '0xffe0', 64 => '0xffc0', 128 => '0xff80', 256 => '0xff00', 512 => '0xfe00', 1024 => '0xfc00', 2048 => '0xf800', 4096 => '0xf000', 8192 => '0xe000' );
|
||||
|
||||
#
|
||||
# Handle an ipset name in the SOURCE or DEST columns of a filter
|
||||
#
|
||||
sub handle_ematch( $$ ) {
|
||||
my ( $setname, $option ) = @_;
|
||||
|
||||
my $options = $option;
|
||||
|
||||
require_capability 'BASIC_EMATCH', 'IPSets', '';
|
||||
|
||||
if ( $setname =~ /^(.*)\[([1-6])\]$/ ) {
|
||||
$setname = $1;
|
||||
my $count = $2;
|
||||
|
||||
$options .= ",$option" while --$count > 0;
|
||||
} elsif ( $setname =~ /^(.*)\[((?:src|dst)(?:,(?:src|dst))){0,5}\]$/ ) {
|
||||
$setname = $1;
|
||||
$options = $2 if supplied $2;
|
||||
|
||||
my @options = split /,/, $options;
|
||||
|
||||
if ( $config{IPSET_WARNINGS} ) {
|
||||
my %typemap = ( src => 'Source', dst => 'Destination' );
|
||||
warning_message( "The '$options[0]' ipset flag is used in a $typemap{$option} column" ), unless $options[0] eq $option;
|
||||
}
|
||||
}
|
||||
|
||||
return " ipset( $setname, $options )";
|
||||
}
|
||||
|
||||
#
|
||||
# Process a record from the tcfilters file
|
||||
#
|
||||
@ -1925,6 +1955,8 @@ sub process_tc_filter1( $$$$$$$$$ ) {
|
||||
|
||||
my $devref;
|
||||
|
||||
my $ematch = '';
|
||||
|
||||
if ( $device =~ /^[\da-fA-F]+$/ && ! $tcdevices{$device} ) {
|
||||
( $device, $devref ) = dev_by_number( hex_value( $device ) );
|
||||
} else {
|
||||
@ -1970,16 +2002,28 @@ sub process_tc_filter1( $$$$$$$$$ ) {
|
||||
my $rule = "filter add dev $devref->{physical} protocol $ip parent $devnum:0 prio $prio u32";
|
||||
|
||||
if ( $source ne '-' ) {
|
||||
if ( $source =~ /^\+/ ) {
|
||||
$ematch = join( ' ', 'match', handle_ematch( $source, 'src' ) );
|
||||
} else {
|
||||
my ( $net , $mask ) = decompose_net( $source );
|
||||
$rule .= "\\\n match $ip32 src $net/$mask";
|
||||
$have_rule = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $dest ne '-' ) {
|
||||
if ( $dest =~ /^\+/ ) {
|
||||
if ( $ematch ) {
|
||||
$ematch = join( ' ', $ematch, handle_ematch( $dest, 'dst' ) );
|
||||
} else {
|
||||
$ematch = join( ' ', 'match', handle_ematch( $dest, 'dst' ) );
|
||||
}
|
||||
} else {
|
||||
my ( $net , $mask ) = decompose_net( $dest );
|
||||
$rule .= "\\\n match $ip32 dst $net/$mask";
|
||||
$have_rule = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $tos ne '-' ) {
|
||||
my $tosval = $tosoptions{$tos};
|
||||
@ -2019,13 +2063,25 @@ sub process_tc_filter1( $$$$$$$$$ ) {
|
||||
}
|
||||
}
|
||||
|
||||
if ( $ematch ) {
|
||||
if ( $have_rule ) {
|
||||
my $tnum = in_hex3 $devref->{tablenumber}++;
|
||||
push @$filtersref, ( "\nrun_tc $rule\\" ,
|
||||
" link $tnum:0" );
|
||||
$rule = "filter add dev $devref->{physical} protocol $ip parent $devnum:0 prio $prio basic ht $tnum:0 match ${ematch}";
|
||||
} else {
|
||||
$rule = "filter add dev $devref->{physical} protocol $ip parent $devnum:0 prio $prio basic match$ ${ematch}";
|
||||
$have_rule = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $portlist eq '-' && $sportlist eq '-' ) {
|
||||
if ( $have_rule ) {
|
||||
push @$filtersref , ( "\nrun_tc $rule\\" ,
|
||||
" flowid $devnum:$class" ,
|
||||
'' );
|
||||
} else {
|
||||
warning_message "Degenerate tcfilter ignored";
|
||||
warning_message "Degenerate tcfilter ignored" unless $ematch;
|
||||
}
|
||||
} else {
|
||||
fatal_error "Ports may not be specified without a PROTO" unless $protonumber;
|
||||
|
Loading…
Reference in New Issue
Block a user