summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2009-04-15 16:00:16 -0700
committerStephen Hemminger <stephen.hemminger@vyatta.com>2009-04-15 16:00:16 -0700
commita6208952a366096657d15c7a955180d02c88b87d (patch)
tree202a85a9df92c74c6cde15e6343552ac83f52974 /lib
parent1943bf57c3566cfd3818e31c894590ea371a35e2 (diff)
downloadvyatta-cfg-qos-a6208952a366096657d15c7a955180d02c88b87d.tar.gz
vyatta-cfg-qos-a6208952a366096657d15c7a955180d02c88b87d.zip
Add Qos matching based on Ethernet MAC address
Use existing u32 infrastructure to match in header
Diffstat (limited to 'lib')
-rw-r--r--lib/Vyatta/Qos/Match.pm116
1 files changed, 64 insertions, 52 deletions
diff --git a/lib/Vyatta/Qos/Match.pm b/lib/Vyatta/Qos/Match.pm
index 765bcb8..7ac9ce9 100644
--- a/lib/Vyatta/Qos/Match.pm
+++ b/lib/Vyatta/Qos/Match.pm
@@ -2,12 +2,12 @@
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
-#
+#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
-#
+#
# This code was originally developed by Vyatta, Inc.
# Portions created by Vyatta are Copyright (C) 2008 Vyatta, Inc.
# All Rights Reserved.
@@ -22,81 +22,93 @@ use warnings;
sub new {
my ( $that, $config ) = @_;
- my $self = { };
+ my $self = {};
my $class = ref($that) || $that;
bless $self, $class;
- foreach my $ip (qw(ip ipv6)) {
- next unless $config->exists($ip);
+ foreach my $proto (qw(ip ipv6 ether)) {
+ next unless $config->exists($proto);
- foreach my $t (qw(vif dev)) {
- die "can not match on $ip and $t\n" if $config->exists($t);
- }
+ foreach my $t (qw(vif dev)) {
+ die "can not match on $proto and $t\n" if $config->exists($t);
+ }
+
+ my %fields;
- # TODO make this data driven?
- my %fields;
- $fields{dsfield} = getDsfield( $config->returnValue("$ip dscp"));
- $fields{protocol} = getProtocol($config->returnValue("$ip protocol"));
- $fields{src} = $config->returnValue("$ip source address");
- $fields{dst} = $config->returnValue("$ip destination address");
- $fields{sport} = $config->returnValue("$ip source port");
- $fields{dport} = $config->returnValue("$ip destination port");
- $self->{$ip} = \%fields;
+ if ( $proto eq 'ether' ) {
+ $fields{protocol} =
+ getProtocol( $config->returnValue("ether protocol") );
+ $fields{src} = $config->returnValue("ether source");
+ $fields{dst} = $config->returnValue("ether destination");
+ }
+ else {
+ $fields{dsfield} =
+ getDsfield( $config->returnValue("$proto dscp") );
+ $fields{protocol} =
+ getProtocol( $config->returnValue("$proto protocol") );
+ $fields{src} = $config->returnValue("$proto source address");
+ $fields{dst} = $config->returnValue("$proto destination address");
+ $fields{sport} = $config->returnValue("$proto source port");
+ $fields{dport} = $config->returnValue("$proto destination port");
+ }
+
+ $self->{$proto} = \%fields;
}
$self->{_vif} = $config->returnValue("vif");
- $self->{_dev} = getIfIndex($config->returnValue("interface"));
+ $self->{_dev} = getIfIndex( $config->returnValue("interface") );
return $self;
}
sub filter {
my ( $self, $dev, $parent, $prio, $dsmark ) = @_;
-
+
# empty match
- return unless %{ $self };
+ return unless %{$self};
# Special case for when dsmarking is used with ds matching
# original dscp is saved in tc_index
if ($dsmark) {
- foreach my $ipver (qw(ip ipv6)) {
- my $ip = $self->{$ipver};
- next unless $ip && $$ip{dsfield};
+ foreach my $ipver (qw(ip ipv6)) {
+ my $ip = $self->{$ipver};
+ next unless $ip && $$ip{dsfield};
- printf "filter add dev %s parent %x: protocol $ipver prio 1",
- $dev, $parent;
- printf " handle %d tcindex", $$ip{dsfield};
- }
- return;
+ printf "filter add dev %s parent %x: protocol $ipver prio 1",
+ $dev, $parent;
+ printf " handle %d tcindex", $$ip{dsfield};
+ }
+ return;
}
- foreach my $ipver (qw(ip ipv6)) {
- my $ip = $self->{$ipver};
- next unless $ip;
-
- printf "filter add dev %s parent %x: prio %d", $dev, $parent, $prio;
- print " protocol $ipver u32";
- print " match $ipver dsfield $$ip{dsfield} 0xff"
- if defined $$ip{dsfield};
- print " match $ipver protocol $$ip{protocol} 0xff"
- if defined $$ip{protocol};
- print " match $ipver src $$ip{src}"
- if defined $$ip{src};
- print " match $ipver sport $$ip{sport} 0xffff"
- if defined $$ip{sport};
- print " match $ipver dst $$ip{dst}"
- if defined $$ip{dst};
- print " match $ipver dport $$ip{dport} 0xffff"
- if defined $$ip{dport};
+ foreach my $proto (qw(ip ipv6 ether)) {
+ my $p = $self->{$proto};
+ next unless $p;
+
+ printf "filter add dev %s parent %x: prio %d", $dev, $parent, $prio;
+ if ($proto ne 'ether') {
+ print " protocol $proto u32";
+ print " match $proto dsfield $$p{dsfield} 0xff" if $$p{dsfield};
+ print " match $proto protocol $$p{protocol} 0xff" if $$p{protocol};
+ } else {
+ my $type = $$p{protocol};
+ $type = 'all' unless $type;
+
+ print " protocol $type u32";
+ }
+ print " match $proto src $$p{src}" if $$p{src};
+ print " match $proto sport $$p{sport} 0xffff" if $$p{sport};
+ print " match $proto dst $$p{dst}" if $$p{dst};
+ print " match $proto dport $$p{dport} 0xffff" if $$p{dport};
}
my $indev = $self->{indev};
- my $vif = $self->{vif};
- if ($vif || $indev) {
- printf "filter add dev %s parent %x: prio %d", $dev, $parent, $prio;
- print " protocol all basic";
- print " match meta\(rt_iif eq $indev\)" if $indev;
- print " match meta\(vlan mask 0xfff eq $vif\)" if $vif;
+ my $vif = $self->{vif};
+ if ( $vif || $indev ) {
+ printf "filter add dev %s parent %x: prio %d", $dev, $parent, $prio;
+ print " protocol all basic";
+ print " match meta\(rt_iif eq $indev\)" if $indev;
+ print " match meta\(vlan mask 0xfff eq $vif\)" if $vif;
}
}