diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Vyatta/Qos/Match.pm | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/lib/Vyatta/Qos/Match.pm b/lib/Vyatta/Qos/Match.pm index f92f849..9456605 100644 --- a/lib/Vyatta/Qos/Match.pm +++ b/lib/Vyatta/Qos/Match.pm @@ -24,6 +24,7 @@ sub new { my ( $that, $config ) = @_; my $self = {}; my $class = ref($that) || $that; + my %filter; bless $self, $class; @@ -41,8 +42,7 @@ sub new { getProtocol( $config->returnValue("ether protocol") ); $fields{src} = $config->returnValue("ether source"); $fields{dst} = $config->returnValue("ether destination"); - } - else { + } else { $fields{dsfield} = getDsfield( $config->returnValue("$proto dscp") ); $fields{protocol} = @@ -54,10 +54,30 @@ sub new { } $self->{$proto} = \%fields; + + my $other = $filter{'protocol'}; + die "Can not match on both $proto and $other protocol in same match\n" + if $other; + + $filter{'protocol'} = $proto; } - $self->{_vif} = $config->returnValue("vif"); - $self->{_indev} = getIfIndex( $config->returnValue("interface") ); + my $vif = $config->returnValue("vif"); + $self->{_vif} = $vif; + + my $iif = $config->returnValue("interface"); + $self->{_indev} = getIfIndex($iif); + $filter{'interface'} = 1 if defined($vif) | defined($iif); + + my $fwmark = $config->returnValue("mark"); + $self->{_fwmark} = $fwmark; + $filter{'mark'} = 1 if $fwmark; + + # Firewall mark, packet contents, and meta data use different + # tc filters + my @filters = (keys %filter); + die "Can not combine matchs ", join(' and ',@filters), "\n" + if $#filters > 0; return $self; } @@ -75,9 +95,9 @@ sub filter { my $ip = $self->{$ipver}; next unless $ip && $$ip{dsfield}; - printf "filter add dev %s parent %x: protocol %s prio $prio", + printf "filter add dev %s parent %x: protocol %s prio $prio", $dev, $parent, $ipver; - printf " handle %s tcindex classid %x:%x\n", + printf " handle %s tcindex classid %x:%x\n", $$ip{dsfield}, $parent, $classid; $prio += 1; @@ -89,12 +109,7 @@ sub filter { my $p = $self->{$proto}; next unless $p; - printf "filter add dev %s parent %x:", $dev, $parent; - if ($prio) { - printf " prio %d", $prio; - $prio += 1; - } - + printf "filter add dev %s parent %x: prio %d", $dev, $parent, $prio; if ($proto eq 'ether') { my $type = $$p{protocol}; $type = 'all' unless $type; @@ -120,14 +135,25 @@ sub filter { print " match $sel dsfield $$p{dsfield} 0xff" if $$p{dsfield}; } print " match $sel protocol $$p{protocol} 0xff" if $$p{protocol}; - + print " match $sel src $$p{src}" if $$p{src}; print " match $sel sport $$p{sport} 0xffff" if $$p{sport}; print " match $sel dst $$p{dst}" if $$p{dst}; print " match $sel dport $$p{dport} 0xffff" if $$p{dport}; } + + print " $police" if $police; + printf " flowid %x:%x\n", $parent, $classid; + return; + } + + my $fwmark = $self->{_fwmark}; + if ( $fwmark ) { + printf "filter add dev %s parent %x: prio %d", $dev, $parent, $prio; + printf " protocol all handle %d fw", $fwmark; print " $police" if $police; printf " flowid %x:%x\n", $parent, $classid; + return; } my $indev = $self->{_indev}; @@ -137,6 +163,7 @@ sub filter { print " protocol all basic"; print " match meta\(rt_iif eq $indev\)" if $indev; print " match meta\(vlan mask 0xfff eq $vif\)" if $vif; + print " $police" if $police; printf " flowid %x:%x\n", $parent, $classid; } |