summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2010-07-08 09:00:41 -0700
committerStephen Hemminger <stephen.hemminger@vyatta.com>2010-07-08 10:41:58 -0700
commite57d0696d3261bc749b747c64442f3b39bacf00e (patch)
tree2603b2477818b9939bc468759e472d25bbaee0f3 /lib
parentb97267962689eed8dd11afecd2d160def3c93dc6 (diff)
downloadvyatta-cfg-qos-e57d0696d3261bc749b747c64442f3b39bacf00e.tar.gz
vyatta-cfg-qos-e57d0696d3261bc749b747c64442f3b39bacf00e.zip
Add ability to match on firewall mark
Bug 5799 - Add matching on firewall mark values Bug 5795 - Block match rules that have multiple underlying filters
Diffstat (limited to 'lib')
-rw-r--r--lib/Vyatta/Qos/Match.pm53
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;
}