summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2010-01-12 08:00:04 -0800
committerStephen Hemminger <stephen.hemminger@vyatta.com>2010-01-12 08:00:04 -0800
commit092a710bbe0ac05607ca9d4417b534597849aaa9 (patch)
treedce90d3674e31cd196e3f0464e9862970d64b8c0 /lib
parent1f8762b9f955bd2b4c024012df783a1d51191a86 (diff)
parent33b8a1ebeb7925890bd744d1bda5f5c6c686c537 (diff)
downloadvyatta-cfg-qos-092a710bbe0ac05607ca9d4417b534597849aaa9.tar.gz
vyatta-cfg-qos-092a710bbe0ac05607ca9d4417b534597849aaa9.zip
Merge branch 'kenwood' of suva.vyatta.com:/git/vyatta-cfg-qos into kenwood
Diffstat (limited to 'lib')
-rw-r--r--lib/Vyatta/Qos/DropTail.pm8
-rw-r--r--lib/Vyatta/Qos/FairQueue.pm11
-rw-r--r--lib/Vyatta/Qos/Match.pm66
-rw-r--r--lib/Vyatta/Qos/NetworkEmulator.pm31
-rw-r--r--lib/Vyatta/Qos/RandomDetect.pm97
-rw-r--r--lib/Vyatta/Qos/RateLimiter.pm11
-rw-r--r--lib/Vyatta/Qos/RoundRobin.pm67
-rw-r--r--lib/Vyatta/Qos/ShaperClass.pm24
-rw-r--r--lib/Vyatta/Qos/TrafficLimiter.pm51
-rw-r--r--lib/Vyatta/Qos/TrafficShaper.pm72
-rw-r--r--lib/Vyatta/Qos/Util.pm2
11 files changed, 123 insertions, 317 deletions
diff --git a/lib/Vyatta/Qos/DropTail.pm b/lib/Vyatta/Qos/DropTail.pm
index 1b14a81..0ff15e9 100644
--- a/lib/Vyatta/Qos/DropTail.pm
+++ b/lib/Vyatta/Qos/DropTail.pm
@@ -47,12 +47,4 @@ sub commands {
printf "%s\n", $cmd;
}
-sub isChanged {
- my ($self, $name) = @_;
- my $config = new Vyatta::Config;
-
- $config->setLevel("qos-policy drop-tail $name");
- return $config->isChanged('queue-limit');
-}
-
1;
diff --git a/lib/Vyatta/Qos/FairQueue.pm b/lib/Vyatta/Qos/FairQueue.pm
index bc3a872..c74cb01 100644
--- a/lib/Vyatta/Qos/FairQueue.pm
+++ b/lib/Vyatta/Qos/FairQueue.pm
@@ -52,15 +52,4 @@ sub commands {
print "\n";
}
-sub isChanged {
- my ( $self, $name ) = @_;
- my $config = new Vyatta::Config;
-
- $config->setLevel("qos-policy fair-queue $name");
- foreach my $attr ('hash-interval', 'queue-limit') {
- return $attr if ($config->isChanged($attr));
- }
- return; # false
-}
-
1;
diff --git a/lib/Vyatta/Qos/Match.pm b/lib/Vyatta/Qos/Match.pm
index 8dda94d..327fbd4 100644
--- a/lib/Vyatta/Qos/Match.pm
+++ b/lib/Vyatta/Qos/Match.pm
@@ -63,7 +63,7 @@ sub new {
}
sub filter {
- my ( $self, $dev, $parent, $prio, $dsmark ) = @_;
+ my ( $self, $dev, $parent, $classid, $prio, $dsmark, $police ) = @_;
# empty match
return unless %{$self};
@@ -75,10 +75,13 @@ sub filter {
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};
- }
+ printf "filter add dev %s parent %x: protocol %s prio $prio",
+ $dev, $parent, $ipver;
+ printf " handle %s tcindex classid %x:%x\n",
+ $$ip{dsfield}, $parent, $classid;
+
+ $prio += 1;
+ }
return;
}
@@ -87,29 +90,54 @@ sub filter {
next unless $p;
printf "filter add dev %s parent %x:", $dev, $parent;
- printf " prio %d", $prio if ($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 {
+ if ($prio) {
+ printf " prio %d", $prio;
+ $prio += 1;
+ }
+
+ if ($proto eq 'ether') {
my $type = $$p{protocol};
$type = 'all' unless $type;
- print " protocol $type u32";
+ if (defined($$p{src}) || defined($$p{dest})) {
+ print " protocol $type u32";
+ print " match ether src $$p{src}" if $$p{src};
+ print " match ether dst $$p{dst}" if $$p{dst};
+ } else {
+ # u32 requires some options to work but basic works
+ print " protocol $type basic";
+ }
+ } else {
+ print " protocol $proto u32";
+
+ # workaround inconsistent usage in tc u32 match
+ my $sel = $proto;
+ if ($proto eq 'ipv6') {
+ $sel = 'ip6';
+ printf " match u16 0x%x 0x0ff0 at 0", hex($$p{dsfield}) << 4,
+ if $$p{dsfield};
+ } else {
+ 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 " 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};
+ print " $police" if $police;
+ printf " flowid %x:%x\n", $parent, $classid;
}
- my $indev = $self->{indev};
- my $vif = $self->{vif};
- if ( $vif || $indev ) {
+ my $indev = $self->{_indev};
+ my $vif = $self->{_vif};
+ if ( defined($vif) || defined($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;
+ print " $police" if $police;
+ printf " flowid %x:%x\n", $parent, $classid;
}
}
diff --git a/lib/Vyatta/Qos/NetworkEmulator.pm b/lib/Vyatta/Qos/NetworkEmulator.pm
index 2a87407..602393c 100644
--- a/lib/Vyatta/Qos/NetworkEmulator.pm
+++ b/lib/Vyatta/Qos/NetworkEmulator.pm
@@ -46,23 +46,28 @@ sub new {
sub commands {
my ( $self, $dev ) = @_;
my $rate = $self->{_rate};
+ my $limit = $self->{_limit};
+ my $delay = $self->{_delay};
if ($rate) {
my $burst = $self->{_burst};
$burst or $burst = "15K";
- printf "qdisc add dev %s root handle 1:0 tbf rate %s burst %s\n",
+ printf "qdisc add dev %s root handle 1:0 tbf rate %s burst %s",
$dev, $rate, $burst;
- printf "qdisc add dev %s parent 1:1 handle 10: netem", $dev;
+ if ($limit) {
+ print " limit $limit";
+ } elsif ($delay) {
+ print " latency $delay";
+ } else {
+ print " latency 50ms";
+ }
+ printf "\nqdisc add dev %s parent 1:1 handle 10: netem", $dev;
} else {
printf "qdisc add dev %s root netem", $dev;
}
-
- my $delay = $self->{_delay};
- print " delay $delay" if ($delay);
-
- my $limit = $self->{_limit};
print " limit $limit" if ($limit);
+ print " delay $delay" if ($delay);
my $drop = $self->{_drop};
print " drop $drop" if ($drop);
@@ -76,16 +81,4 @@ sub commands {
print "\n";
}
-sub isChanged {
- my ( $self, $name ) = @_;
- my $config = new Vyatta::Config;
-
- $config->setLevel("qos-policy network-emulator $name");
- foreach my $attr ( "bandwidth", "burst", "queue-limit", "network-delay",
- "packet-loss", "packet-corruption", "packet-reordering", ) {
- return $attr if ( $config->isChanged($attr) );
- }
- return;
-}
-
1;
diff --git a/lib/Vyatta/Qos/RandomDetect.pm b/lib/Vyatta/Qos/RandomDetect.pm
index 1918711..e7f16f3 100644
--- a/lib/Vyatta/Qos/RandomDetect.pm
+++ b/lib/Vyatta/Qos/RandomDetect.pm
@@ -29,18 +29,6 @@ use warnings;
require Vyatta::Config;
use Vyatta::Qos::Util qw/getRate getAutoRate getTime/;
-# default values for different precedence levels
-my @default_fields = (
- { 'min-threshold' => 9, 'max-threshold' => 18, 'mark-probability' => 1/2 },
- { 'min-threshold' => 10, 'max-threshold' => 18, 'mark-probability' => 5/9 },
- { 'min-threshold' => 11, 'max-threshold' => 18, 'mark-probability' => .1 },
- { 'min-threshold' => 12, 'max-threshold' => 18, 'mark-probability' => 2/3 },
- { 'min-threshold' => 13, 'max-threshold' => 18, 'mark-probability' => .1 },
- { 'min-threshold' => 14, 'max-threshold' => 18, 'mark-probability' => 7/9 },
- { 'min-threshold' => 15, 'max-threshold' => 18, 'mark-probability' => 5/6 },
- { 'min-threshold' => 16, 'max-threshold' => 18, 'mark-probability' => 8/9 },
-);
-
# Create a new instance based on config information
sub new {
my ( $that, $config, $name ) = @_;
@@ -66,22 +54,37 @@ sub getPrecedence {
my @precedence;
for ( my $i = 0 ; $i <= 7 ; $i++ ) {
- my $defaults = $default_fields[$i];
- my %param;
-
+ my %pred;
+
$config->setLevel("$level precedence $i");
- foreach my $field (keys %$defaults) {
- my $val = $config->returnValue($field);
-
- if ( !defined $val ) {
- $param{$field} = $defaults->{$field};
- } elsif ( $field eq 'mark-probability' ) {
- $param{$field} = 1 / $val;
- } else {
- $param{$field} = $val;
- }
- }
- $precedence[$i] = \%param;
+
+ # Compute some sane defaults based on predence and max-threshold
+ $pred{qmax} = $config->returnValue('maximum-threshold');
+ $pred{qmax} = 18 unless $pred{qmax};
+
+ $pred{qmin} = $config->returnValue('minimum-threshold');
+ if ($pred{qmin}) {
+ die "min-threshold: $pred{qmin} >= max-threshold: $pred{qmax}\n"
+ if ($pred{qmin} >= $pred{qmax});
+ } else {
+ $pred{qmin} = ((9 + $i) * $pred{qmax})/ 18;
+ }
+
+ $pred{qlim} = $config->returnValue('queue-limit');
+ if ($pred{qlim}) {
+ die "queue-limit: $pred{qlim} < max-threshold: $pred{qmax}\n"
+ if ($pred{qlim} < $pred{qmax});
+ } else {
+ $pred{qlim} = 4 * $pred{qmax};
+ }
+
+ my $mp = $config->returnValue('mark-probablilty');
+ $pred{prob} = (defined $mp) ? (1 / $mp) : (1 / 10);
+
+ my $avgpkt = $config->returnValue('average-packet');
+ $pred{avpkt} = (defined $avgpkt) ? $avgpkt : 1024;
+
+ $precedence[$i] = \%pred;
}
return @precedence;
@@ -98,7 +101,7 @@ sub commands {
$dev, $root;
# 2. use tcindex filter to convert tc_index to precedence
- #
+ #
# Precedence Field: the three leftmost bits in the TOS octet of an IPv4
# header.
@@ -113,40 +116,18 @@ sub commands {
# set VQ parameters
for ( my $i = 0 ; $i <= 7 ; $i++ ) {
- my $param = $precedence->[$i];
- my $qmin = $param->{'min-threshold'};
- my $qmax = $param->{'max-threshold'};
- my $prob = $param->{'mark-probability'};
+ my $pred = $precedence->[$i];
+ my $avg = $pred->{avpkt};
+ my $burst = ( 2 * $pred->{qmin} + $pred->{qmax} ) / 3;
printf "qdisc change dev %s handle %x:0 gred", $dev, $root+1, $i;
- printf " limit %dK min %dK max %dK avpkt 1K", 4 * $qmax, $qmin, $qmax;
- printf " burst %d bandwidth %d probability %f DP %d prio %d\n",
- ( 2 * $qmin + $qmax ) / 3, $rate, $prob, $i, 8-$i;
- }
-}
+ printf " limit %d min %d max %d avpkt %d",
+ $pred->{qlim} * $avg, $pred->{qmin} * $avg,
+ $pred->{qmax} * $avg, $avg;
-# Walk configuration tree and look for changed nodes
-# The configuration system should do this but doesn't do it right
-sub isChanged {
- my ( $self, $name ) = @_;
- my $config = new Vyatta::Config;
-
- $config->setLevel("qos-policy random-detect $name");
-
- return 'bandwidth' if ( $config->isChanged('bandwidth') );
-
- my %precedenceNodes = $config->listNodeStatus('precedence');
- while ( my ( $pred, $status ) = each %precedenceNodes ) {
- return "precedence $pred" if ( $status ne 'static' );
-
- my $defaults = $default_fields[0];
- foreach my $attr (keys %$defaults) {
- return "precedence $pred $attr"
- if ( $config->isChanged("precedence $pred $attr") );
- }
+ printf " burst %d bandwidth %d probability %f DP %d prio %d\n",
+ $burst, $rate, $pred->{prob}, $i, 8-$i;
}
-
- return; # false
}
1;
diff --git a/lib/Vyatta/Qos/RateLimiter.pm b/lib/Vyatta/Qos/RateLimiter.pm
index c20646e..ac0cd2c 100644
--- a/lib/Vyatta/Qos/RateLimiter.pm
+++ b/lib/Vyatta/Qos/RateLimiter.pm
@@ -55,15 +55,4 @@ sub commands {
$dev, $self->{_rate}, $self->{_latency}, $self->{_burst};
}
-sub isChanged {
- my ($self, $name) = @_;
- my $config = new Vyatta::Config;
-
- $config->setLevel("qos-policy rate-limit $name");
- foreach my $attr ('bandwidth', 'burst', 'latency') {
- return $attr if ($config->isChanged($attr));
- }
- return; # false
-}
-
1;
diff --git a/lib/Vyatta/Qos/RoundRobin.pm b/lib/Vyatta/Qos/RoundRobin.pm
index 83a41b7..a1d7787 100644
--- a/lib/Vyatta/Qos/RoundRobin.pm
+++ b/lib/Vyatta/Qos/RoundRobin.pm
@@ -41,16 +41,9 @@ sub _getClasses {
my @classes;
my $config = new Vyatta::Config;
- $config->setLevel($level);
- my $default;
- if ( $config->exists("default") ) {
- $config->setLevel("$level default");
- $default = new Vyatta::Qos::ShaperClass($config);
- $config->setLevel($level);
- }
- else {
- $default = new Vyatta::Qos::ShaperClass;
- }
+ $config->setLevel("$level default");
+ my $default = new Vyatta::Qos::ShaperClass($config);
+
push @classes, $default;
$default->{id} = 1;
@@ -75,61 +68,9 @@ sub commands {
$class->gen_class( $dev, 'drr', $parent );
$class->gen_leaf( $dev, $parent );
foreach my $match ( $class->matchRules() ) {
- $match->filter( $dev, $parent, 1 );
- printf " classid %x:%x\n", $parent, $class->{id};
- }
- }
-}
-
-# Walk configuration tree and look for changed nodes
-# The configuration system should do this but doesn't do it right
-sub isChanged {
- my ( $self, $name ) = @_;
- my $config = new Vyatta::Config;
-
- $config->setLevel("qos-policy round-robin $name");
-
- return 'quantum' if ( $config->isChanged('quantum') );
-
- foreach my $attr (qw(queue-limit queue-type)) {
- return "default $attr" if ( $config->isChanged("default $attr") );
- }
-
- my %classNodes = $config->listNodeStatus('class');
- while ( my ( $class, $status ) = each %classNodes ) {
- return "class $class" if ( $status ne 'static' );
-
- foreach my $attr (qw(queue-limit queue-type)) {
- return "class $class $attr"
- if ( $config->isChanged("class $class $attr") );
- }
-
- my %matchNodes = $config->listNodeStatus("class $class match");
- while ( my ( $match, $status ) = each %matchNodes ) {
- my $level = "class $class match $match";
- if ( $status ne 'static' ) {
- return $level;
- }
-
- foreach my $parm (
- (
- 'vif',
- 'interface',
- 'ip protocol',
- 'ip source address',
- 'ip destination address',
- 'ip source port',
- 'ip destination port'
- )
- )
- {
- return "$level $parm"
- if ( $config->isChanged("$level $parm") );
- }
+ $match->filter( $dev, $parent, $class->{id}, 1);
}
}
-
- return; # false
}
1;
diff --git a/lib/Vyatta/Qos/ShaperClass.pm b/lib/Vyatta/Qos/ShaperClass.pm
index 3a25233..361eb57 100644
--- a/lib/Vyatta/Qos/ShaperClass.pm
+++ b/lib/Vyatta/Qos/ShaperClass.pm
@@ -168,18 +168,12 @@ sub fifoQdisc {
#
sub redQdisc {
my ( $self, $dev, $rate ) = @_;
- my $qmax = ( $rate * 100 ) / 8000;
- my $qmin = $qmax / 3;
my $avg = 1024;
- my $burst = ( 2 * $qmin + $qmax ) / (3*$avg);
-
+ my $qmax = (defined $rate) ? (( $rate * 100 ) / 8000) : (18 * $avg);
+ my $qmin = $qmax / 3;
+ my $burst = ( 2 * $qmin + $qmax ) / (3 * $avg);
my $limit = $self->{_limit};
- my $qlimit;
- if ($limit) {
- $qlimit = $limit * $avg;
- } else {
- $qlimit = 4 * $qmax;
- }
+ my $qlimit = (defined $limit) ? ($limit * $avg) : (4 * $qmax);
printf "red limit %d min %d max %d avpkt %d", $qlimit, $qmin, $qmax, $avg;
printf " burst %d probability 0.1 bandwidth %s ecn\n", $burst, $rate;
@@ -215,11 +209,15 @@ sub gen_class {
sub gen_leaf {
my ( $self, $dev, $parent, $rate ) = @_;
+ my $qtype = $self->{_qdisc};
+ return unless $qtype; # default is okay
- printf "qdisc add dev %s parent %x:%x ", $dev, $parent, $self->{id};
+ my $q = $qdiscOptions{$qtype};
+ die "Unknown queue-type $qtype\n"
+ unless $q;
- my $q = $qdiscOptions{ $self->{_qdisc} };
- $q->( $self, $dev, $rate ) if ($q);
+ printf "qdisc add dev %s parent %x:%x ", $dev, $parent, $self->{id};
+ $q->( $self, $dev, $rate );
}
sub dsmarkClass {
diff --git a/lib/Vyatta/Qos/TrafficLimiter.pm b/lib/Vyatta/Qos/TrafficLimiter.pm
index fd3460c..e5731d0 100644
--- a/lib/Vyatta/Qos/TrafficLimiter.pm
+++ b/lib/Vyatta/Qos/TrafficLimiter.pm
@@ -83,56 +83,13 @@ sub commands {
printf "qdisc add dev %s handle %x: ingress\n", $dev, $parent;
foreach my $class (@$classes) {
foreach my $match ( $class->matchRules() ) {
- $match->filter( $dev, $parent, $class->{priority} );
- printf " police rate %s burst %s drop flowid :%x\n",
- $class->{rate}, $class->{burst}, $class->{id};
- }
- }
-}
-
-# Walk configuration tree and look for changed nodes
-# The configuration system should do this but doesn't do it right
-sub isChanged {
- my ( $self, $name ) = @_;
- my $config = new Vyatta::Config;
+ my $police = " police rate " . $class->{rate}
+ . " burst " . $class->{burst};
- $config->setLevel("qos-policy traffic-limiter $name");
- my %classNodes = $config->listNodeStatus('class');
- while ( my ( $class, $status ) = each %classNodes ) {
- if ( $status ne 'static' ) {
- return "class $class";
- }
-
- foreach my $attr ( 'bandwidth', 'burst', 'priority' ) {
- if ( $config->isChanged("class $class $attr") ) {
- return "class $class $attr";
- }
- }
-
- my %matchNodes = $config->listNodeStatus("class $class match");
- while ( my ( $match, $status ) = each %matchNodes ) {
- my $level = "class $class match $match";
- if ( $status ne 'static' ) {
- return $level;
- }
-
- foreach my $parm (
- 'vif',
- 'interface',
- 'ip dscp',
- 'ip protocol',
- 'ip source address',
- 'ip destination address',
- 'ip source port',
- 'ip destination port'
- )
- {
- return "$level $parm" if ( $config->isChanged("$level $parm") );
- }
+ $match->filter( $dev, $parent, $class->{id}, $class->{priority},
+ undef, $police );
}
}
-
- return; # false
}
1;
diff --git a/lib/Vyatta/Qos/TrafficShaper.pm b/lib/Vyatta/Qos/TrafficShaper.pm
index c808c7d..f89ae60 100644
--- a/lib/Vyatta/Qos/TrafficShaper.pm
+++ b/lib/Vyatta/Qos/TrafficShaper.pm
@@ -72,8 +72,10 @@ sub _checkClasses {
my $rate = shift;
my $default = shift;
- # if auto, can't check at create must wait for policy to be applied
+ # if auto, can't check for constraints until later
$rate = ( $rate eq "auto") ? undef : getRate($rate);
+ die "Bandwidth not defined for default traffic\n"
+ unless $default->{_rate};
$default->rateCheck( $rate, "$level default" ) if $rate;
foreach my $class (@_) {
@@ -132,8 +134,7 @@ sub commands {
foreach my $class (@$classes) {
$class->dsmarkClass( 1, $dev );
foreach my $match ( $class->matchRules() ) {
- $match->filter( $dev, 1, 1 );
- printf " classid %x:%x\n", $parent, $class->{id};
+ $match->filter( $dev, $parent, $class->{id}, 1 );
}
}
@@ -151,72 +152,9 @@ sub commands {
$class->gen_leaf( $dev, $parent, $rate );
foreach my $match ( $class->matchRules() ) {
- $match->filter( $dev, $parent, 1, $class->{dsmark} );
- printf " classid %x:%x\n", $parent, $class->{id};
+ $match->filter( $dev, $parent, $class->{id}, 1, $class->{dsmark} );
}
}
}
-# Walk configuration tree and look for changed nodes
-# The configuration system should do this but doesn't do it right
-sub isChanged {
- my ( $self, $name ) = @_;
- my $config = new Vyatta::Config;
- my @attributes = qw(bandwidth burst ceiling priority queue-limit queue-type);
-
- $config->setLevel("qos-policy traffic-shaper $name");
-
- if ( $config->isChanged('bandwidth') ) {
- return 'bandwidth';
- }
-
- foreach my $attr (@attributes) {
- if ( $config->isChanged("default $attr") ) {
- return "default $attr";
- }
- }
-
- my %classNodes = $config->listNodeStatus('class');
- while ( my ( $class, $status ) = each %classNodes ) {
- if ( $status ne 'static' ) {
- return "class $class";
- }
-
- foreach my $attr (@attributes) {
- if ( $config->isChanged("class $class $attr") ) {
- return "class $class $attr";
- }
- }
-
- my %matchNodes = $config->listNodeStatus("class $class match");
- while ( my ( $match, $status ) = each %matchNodes ) {
- my $level = "class $class match $match";
- if ( $status ne 'static' ) {
- return $level;
- }
-
- foreach my $parm (
- 'vif',
- 'ether destination',
- 'ether source',
- 'ether protocol',
- 'interface',
- 'ip dscp',
- 'ip protocol',
- 'ip source address',
- 'ip destination address',
- 'ip source port',
- 'ip destination port'
- )
- {
- if ( $config->isChanged("$level $parm") ) {
- return "$level $parm";
- }
- }
- }
- }
-
- return; # false
-}
-
1;
diff --git a/lib/Vyatta/Qos/Util.pm b/lib/Vyatta/Qos/Util.pm
index 242e2b4..9686120 100644
--- a/lib/Vyatta/Qos/Util.pm
+++ b/lib/Vyatta/Qos/Util.pm
@@ -300,7 +300,7 @@ sub ethtoolRate {
# Get rate of real device (ignore vlan)
$dev =~ s/\.[0-9]+$//;
- open( my $ethtool, "/usr/sbin/ethtool $dev 2>/dev/null |" )
+ open( my $ethtool, "sudo /usr/sbin/ethtool $dev 2>/dev/null |" )
or die "ethtool failed: $!\n";
# ethtool produces: