diff options
author | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2010-01-12 08:00:04 -0800 |
---|---|---|
committer | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2010-01-12 08:00:04 -0800 |
commit | 092a710bbe0ac05607ca9d4417b534597849aaa9 (patch) | |
tree | dce90d3674e31cd196e3f0464e9862970d64b8c0 | |
parent | 1f8762b9f955bd2b4c024012df783a1d51191a86 (diff) | |
parent | 33b8a1ebeb7925890bd744d1bda5f5c6c686c537 (diff) | |
download | vyatta-cfg-qos-092a710bbe0ac05607ca9d4417b534597849aaa9.tar.gz vyatta-cfg-qos-092a710bbe0ac05607ca9d4417b534597849aaa9.zip |
Merge branch 'kenwood' of suva.vyatta.com:/git/vyatta-cfg-qos into kenwood
31 files changed, 258 insertions, 370 deletions
diff --git a/debian/changelog b/debian/changelog index ddb1bbf..16cd265 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,64 @@ +vyatta-cfg-qos (0.13.14) unstable; urgency=low + + * added required keyword to help text. + + -- Michael Larson <slioch@slioch.vyatta.com> Mon, 30 Nov 2009 16:00:24 -0800 + +vyatta-cfg-qos (0.13.13) unstable; urgency=low + + * dependency update + + -- Michael Larson <slioch@slioch.vyatta.com> Fri, 13 Nov 2009 14:01:25 -0800 + +vyatta-cfg-qos (0.13.12) unstable; urgency=low + + * Fix parse error found by check_tmpl script. + + -- Stig Thormodsrud <stig@vyatta.com> Thu, 05 Nov 2009 16:47:32 -0800 + +vyatta-cfg-qos (0.13.11) unstable; urgency=low + + * add support for priority in project + + -- slioch <slioch@eng-140.vyatta.com> Tue, 20 Oct 2009 16:16:15 -0700 + +vyatta-cfg-qos (0.13.10) unstable; urgency=low + + * Use sudo when getting speed + * Allow random-detect for Qos policy types without rate + * Allow random-detect for round-robin subqueue + * Allow setting queue limit and average packet size + * Handle round-robin without configuration of default + * Fix management of delete of policy in use + * Fix netem bandwidth (TBF) setup + * Change initialization of WRED parameters + * IPV6 match fix + * Cleanup how qos-policy change detection works + * remove pseudo-ethernet vif + * Address issues in traffic-shaper match + * Require bandwidth setting for default class + * Fix update (apply-policy) at end + * Fix issues with vif match + * Ignore deleted policy on end test + * Fix DSCP field match with set-dscp + * Fix policy update + * Fix mixed protocol matches + * Fix IPV6 traffic-class match + * Remove extra quote that caused shell error in fair-queue + * Don't allow random-detect type for round-robin queue type + * random-detect needs qmax > qmin + * Fix match rules for traffic limiter + * Fix perl error when attempting to delete qos policy + * Allow update to interface if not present yet + + -- Stephen Hemminger <shemminger@lenny.localdomain> Thu, 01 Oct 2009 13:52:13 -0700 + +vyatta-cfg-qos (0.13.9) unstable; urgency=low + + * Add wireless config + + -- Stephen Hemminger <stephen.hemminger@vyatta.com> Thu, 20 Aug 2009 13:48:54 -0700 + vyatta-cfg-qos (0.13.8) unstable; urgency=low [ Stephen Hemminger ] diff --git a/debian/control b/debian/control index d9dce92..a5ce364 100644 --- a/debian/control +++ b/debian/control @@ -11,7 +11,7 @@ Depends: sed (>= 4.1.5), perl (>= 5.8.8), procps (>= 1:3.2.7-3), coreutils (>= 5.97-5.3), - vyatta-cfg, + vyatta-cfg (>= 0.15.33), vyatta-bash | bash (>= 3.1), iproute | vyatta-iproute, sudo, diff --git a/gen-interface-templates.pl b/gen-interface-templates.pl index 03133ad..31816aa 100755 --- a/gen-interface-templates.pl +++ b/gen-interface-templates.pl @@ -33,6 +33,7 @@ my %interface_hash = ( 'ethernet/node.tag/pppoe/node.tag' => 'pppoe$VAR(@)', 'ethernet/node.tag/vif/node.tag' => '$VAR(../@).$VAR(@)', 'ethernet/node.tag/vif/node.tag/pppoe/node.tag' => 'pppoe$VAR(@)', + 'wireless/node.tag' => '$VAR(@)', 'bonding/node.tag' => '$VAR(@)', 'bonding/node.tag/vif/node.tag' => '$VAR(../@).$VAR(@)', 'pseudo-ethernet/node.tag' => '$VAR(@)', 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: diff --git a/scripts/vyatta-qos.pl b/scripts/vyatta-qos.pl index 693da36..487fdc6 100755 --- a/scripts/vyatta-qos.pl +++ b/scripts/vyatta-qos.pl @@ -155,6 +155,12 @@ sub update_interface { my $shaper = make_policy( $policy, $name, $direction ); exit 1 unless $shaper; + if ( ! -d "/sys/class/net/$device" ) { + warn "$device not present yet, qos-policy will be applied later\n"; + return; + } + + # Remove old policy delete_interface( $device, $direction ); @@ -182,7 +188,8 @@ sub update_interface { } } -# return array of names using given qos-policy + +# return array of references to (name, direction, policy) sub interfaces_using { my $policy = shift; my $config = new Vyatta::Config; @@ -191,9 +198,17 @@ sub interfaces_using { foreach my $name ( getInterfaces() ) { my $intf = new Vyatta::Interface($name); next unless $intf; - - $config->setLevel( $intf->path() ); - push @inuse, $name if ( $config->exists("qos-policy $policy") ); + my $level = $intf->path() . ' qos-policy'; + $config->setLevel($level); + + foreach my $direction ($config->listNodes()) { + my $cur = $config->returnValue($direction); + next unless $cur; + + # these are arguments to update_interface() + push @inuse, [ $name, $direction, $policy ] + if ($cur eq $policy); + } } return @inuse; } @@ -201,10 +216,12 @@ sub interfaces_using { # check if policy name(s) are still in use sub delete_policy { while ( my $name = shift ) { - my @inuse = interfaces_using($name); + # interfaces_using returns array of array and only want name + my @inuse = map { @$_[0] } interfaces_using($name); - die "QoS policy still in use on ", join( ' ', @inuse ), "\n" - if (@inuse); + die "Can not delete qos-policy $name, still applied" + . " to interface ", join(' ', @inuse), "\n" + if @inuse; } } @@ -219,19 +236,17 @@ sub create_policy { # Configuration changed, reapply to all interfaces. sub apply_policy { - my $config = new Vyatta::Config; - - while ( my $name = shift ) { - foreach my $device ( interfaces_using($name) ) { - my $intf = new Vyatta::Interface($device); - - $config->setLevel( $intf->path() ); - foreach my $direction ( $config->listNodes('qos-policy') ) { - next unless $config->exists("qos-policy $direction $name"); - - update_interface( $device, $direction, $name ); - } - } + while (my $name = shift) { + my @usedby = interfaces_using($name); + if (@usedby) { + foreach my $args (@usedby) { + update_interface( @$args ); + } + } elsif (my $policy = find_policy($name)) { + # Recheck the policy, might have new errors. + my $shaper = make_policy( $policy, $name ); + exit 1 unless $shaper; + } } } @@ -240,7 +255,7 @@ sub usage { usage: vyatta-qos.pl --list-policy direction vyatta-qos.pl --create-policy policy-type policy-name vyatta-qos.pl --delete-policy policy-name - vyatta-qos.pl --apply-policy policy-name + vyatta-qos.pl --apply-policy policy-type policy-name vyatta-qos.pl --update-interface interface direction policy-name vyatta-qos.pl --delete-interface interface direction diff --git a/templates/qos-policy/drop-tail/node.def b/templates/qos-policy/drop-tail/node.def index 111bb63..1bbb25f 100644 --- a/templates/qos-policy/drop-tail/node.def +++ b/templates/qos-policy/drop-tail/node.def @@ -3,6 +3,6 @@ type: txt help: Set drop tail queue (FIFO) policy syntax:expression: pattern $VAR(@) "^[[:alnum:]][-_[:alnum:]]*$" ; "only alpha-numeric policy name allowed" -create: /opt/vyatta/sbin/vyatta-qos.pl --create-policy "$VAR(.)" "$VAR(@)" -delete: /opt/vyatta/sbin/vyatta-qos.pl --delete-policy "$VAR(@)" -end: /opt/vyatta/sbin/vyatta-qos.pl --apply-policy "$VAR(@)" +create: /opt/vyatta/sbin/vyatta-qos.pl --create-policy $VAR(.) $VAR(@) +delete: /opt/vyatta/sbin/vyatta-qos.pl --delete-policy $VAR(@) +end: /opt/vyatta/sbin/vyatta-qos.pl --apply-policy $VAR(@) diff --git a/templates/qos-policy/drop-tail/node.tag/queue-limit/node.def b/templates/qos-policy/drop-tail/node.tag/queue-limit/node.def index 49c47b4..fe3b4dd 100644 --- a/templates/qos-policy/drop-tail/node.tag/queue-limit/node.def +++ b/templates/qos-policy/drop-tail/node.tag/queue-limit/node.def @@ -1,2 +1,2 @@ type: u32 -help: Set maximum queue size (packets) +help: Set maximum queue size (packets) [REQUIRED] diff --git a/templates/qos-policy/fair-queue/node.def b/templates/qos-policy/fair-queue/node.def index ac9dc2d..1966ab6 100644 --- a/templates/qos-policy/fair-queue/node.def +++ b/templates/qos-policy/fair-queue/node.def @@ -3,6 +3,6 @@ type: txt help: Set fair queueing policy syntax:expression: pattern $VAR(@) "^[[:alnum:]][-_[:alnum:]]*$" ; "only alpha-numeric policy name allowed" -create: /opt/vyatta/sbin/vyatta-qos.pl --create-policy "$VAR(.)" "$VAR(@)" -delete: /opt/vyatta/sbin/vyatta-qos.pl --delete-policy "$VAR(@)" -end: /opt/vyatta/sbin/vyatta-qos.pl --apply-policy "$VAR(@)" +create: /opt/vyatta/sbin/vyatta-qos.pl --create-policy $VAR(.) $VAR(@) +delete: /opt/vyatta/sbin/vyatta-qos.pl --delete-policy $VAR(@) +end: /opt/vyatta/sbin/vyatta-qos.pl --apply-policy $VAR(@) diff --git a/templates/qos-policy/network-emulator/node.def b/templates/qos-policy/network-emulator/node.def index 4a3e570..9a89c53 100644 --- a/templates/qos-policy/network-emulator/node.def +++ b/templates/qos-policy/network-emulator/node.def @@ -3,6 +3,6 @@ type: txt help: Setup network emulator policy syntax:expression: pattern $VAR(@) "^[[:alnum:]][-_[:alnum:]]*$" ; "only alpha-numeric policy name allowed" -create: /opt/vyatta/sbin/vyatta-qos.pl --create-policy "$VAR(.)" "$VAR(@)" -delete: /opt/vyatta/sbin/vyatta-qos.pl --delete-policy "$VAR(@)" -end: /opt/vyatta/sbin/vyatta-qos.pl --apply-policy "$VAR(@)" +create: /opt/vyatta/sbin/vyatta-qos.pl --create-policy $VAR(.) $VAR(@) +delete: /opt/vyatta/sbin/vyatta-qos.pl --delete-policy $VAR(@) +end: /opt/vyatta/sbin/vyatta-qos.pl --apply-policy $VAR(@) diff --git a/templates/qos-policy/node.def b/templates/qos-policy/node.def index e692c0f..e6a2afc 100644 --- a/templates/qos-policy/node.def +++ b/templates/qos-policy/node.def @@ -1 +1,2 @@ +priority: 900 help: Configure Quality of Service (QOS) policy type diff --git a/templates/qos-policy/random-detect/node.def b/templates/qos-policy/random-detect/node.def index 02911a1..7dc1caa 100644 --- a/templates/qos-policy/random-detect/node.def +++ b/templates/qos-policy/random-detect/node.def @@ -3,6 +3,6 @@ type: txt help: Set Weighted Random Early Detect policy syntax:expression: pattern $VAR(@) "^[[:alnum:]][-_[:alnum:]]*$" ; "only alpha-numeric policy name allowed" -create: /opt/vyatta/sbin/vyatta-qos.pl --create-policy "$VAR(.)" "$VAR(@)" -delete: /opt/vyatta/sbin/vyatta-qos.pl --delete-policy "$VAR(@)" -end: /opt/vyatta/sbin/vyatta-qos.pl --apply-policy "$VAR(@)" +create: /opt/vyatta/sbin/vyatta-qos.pl --create-policy $VAR(.) $VAR(@) +delete: /opt/vyatta/sbin/vyatta-qos.pl --delete-policy $VAR(@) +end: /opt/vyatta/sbin/vyatta-qos.pl --apply-policy $VAR(@) diff --git a/templates/qos-policy/random-detect/node.tag/precedence/node.tag/average-packet/node.def b/templates/qos-policy/random-detect/node.tag/precedence/node.tag/average-packet/node.def new file mode 100644 index 0000000..23cdb0f --- /dev/null +++ b/templates/qos-policy/random-detect/node.tag/precedence/node.tag/average-packet/node.def @@ -0,0 +1,4 @@ +type: u32 +help: Average packet size (bytes) +default: 1024 +syntax:expression: $VAR(@) >= 16 && $VAR(@) <= 10240 ; "Average packet size must be between 16 and 10240" diff --git a/templates/qos-policy/random-detect/node.tag/precedence/node.tag/queue-limit/node.def b/templates/qos-policy/random-detect/node.tag/precedence/node.tag/queue-limit/node.def new file mode 100644 index 0000000..49c47b4 --- /dev/null +++ b/templates/qos-policy/random-detect/node.tag/precedence/node.tag/queue-limit/node.def @@ -0,0 +1,2 @@ +type: u32 +help: Set maximum queue size (packets) diff --git a/templates/qos-policy/rate-limit/node.def b/templates/qos-policy/rate-limit/node.def index 2e3eed1..57bf98e 100644 --- a/templates/qos-policy/rate-limit/node.def +++ b/templates/qos-policy/rate-limit/node.def @@ -3,6 +3,6 @@ type: txt help: Set rate limiting policy syntax:expression: pattern $VAR(@) "^[[:alnum:]][-_[:alnum:]]*$" ; "only alpha-numeric policy name allowed" -create: /opt/vyatta/sbin/vyatta-qos.pl --create-policy "$VAR(.)" "$VAR(@)" -delete: /opt/vyatta/sbin/vyatta-qos.pl --delete-policy "$VAR(@)" -end: /opt/vyatta/sbin/vyatta-qos.pl --apply-policy "$VAR(@)" +create: /opt/vyatta/sbin/vyatta-qos.pl --create-policy $VAR(.) $VAR(@) +delete: /opt/vyatta/sbin/vyatta-qos.pl --delete-policy $VAR(@) +end: /opt/vyatta/sbin/vyatta-qos.pl --apply-policy $VAR(@) diff --git a/templates/qos-policy/round-robin/node.def b/templates/qos-policy/round-robin/node.def index daf795a..4427e1a 100644 --- a/templates/qos-policy/round-robin/node.def +++ b/templates/qos-policy/round-robin/node.def @@ -3,6 +3,6 @@ type: txt help: Set deficit round robin based policy syntax:expression: pattern $VAR(@) "^[[:alnum:]][-_[:alnum:]]*$" ; "only alpha-numeric policy name allowed" -create: /opt/vyatta/sbin/vyatta-qos.pl --create-policy "$VAR(.)" "$VAR(@)" -delete: /opt/vyatta/sbin/vyatta-qos.pl --delete-policy "$VAR(@)" -end: /opt/vyatta/sbin/vyatta-qos.pl --apply-policy "$VAR(@)" +create: /opt/vyatta/sbin/vyatta-qos.pl --create-policy $VAR(.) $VAR(@) +delete: /opt/vyatta/sbin/vyatta-qos.pl --delete-policy $VAR(@) +end: /opt/vyatta/sbin/vyatta-qos.pl --apply-policy $VAR(@) diff --git a/templates/qos-policy/round-robin/node.tag/class/node.tag/queue-type/node.def b/templates/qos-policy/round-robin/node.tag/class/node.tag/queue-type/node.def index 61f9506..ecbcede 100644 --- a/templates/qos-policy/round-robin/node.tag/class/node.tag/queue-type/node.def +++ b/templates/qos-policy/round-robin/node.tag/class/node.tag/queue-type/node.def @@ -1,9 +1,8 @@ type: txt -default: "fair-queue" +default: "drop-tail" syntax:expression: $VAR(@) in "fair-queue", "priority", "drop-tail"; "Unknown queue-type" help: Set the queue type for this class comp_help:Possible completions fair-queue\tStochastic Fair Queue (SFQ) drop-tail\tFirst-In-First-Out (FIFO) priority\tPriority queueing based on DSCP - diff --git a/templates/qos-policy/round-robin/node.tag/default/queue-type/node.def b/templates/qos-policy/round-robin/node.tag/default/queue-type/node.def index 295c04c..61f9506 100644 --- a/templates/qos-policy/round-robin/node.tag/default/queue-type/node.def +++ b/templates/qos-policy/round-robin/node.tag/default/queue-type/node.def @@ -1,10 +1,9 @@ type: txt default: "fair-queue" -syntax:expression: $VAR(@) in "fair-queue", "priority", "drop-tail", "random-detect"; "Unknown queue-type" +syntax:expression: $VAR(@) in "fair-queue", "priority", "drop-tail"; "Unknown queue-type" help: Set the queue type for this class comp_help:Possible completions fair-queue\tStochastic Fair Queue (SFQ) drop-tail\tFirst-In-First-Out (FIFO) priority\tPriority queueing based on DSCP - random-detect\tRandom Early Detection (RED) diff --git a/templates/qos-policy/traffic-limiter/node.def b/templates/qos-policy/traffic-limiter/node.def index b411273..f8bdf26 100644 --- a/templates/qos-policy/traffic-limiter/node.def +++ b/templates/qos-policy/traffic-limiter/node.def @@ -3,6 +3,6 @@ type: txt help: Set traffic input limiting policy syntax:expression: pattern $VAR(@) "^[[:alnum:]][-_[:alnum:]]*$" ; "only alpha-numeric policy name allowed" -create: /opt/vyatta/sbin/vyatta-qos.pl --create-policy "$VAR(.)" "$VAR(@)" -delete: /opt/vyatta/sbin/vyatta-qos.pl --delete-policy "$VAR(@)" -end: /opt/vyatta/sbin/vyatta-qos.pl --apply-policy "$VAR(@)" +create: /opt/vyatta/sbin/vyatta-qos.pl --create-policy $VAR(.) $VAR(@) +delete: /opt/vyatta/sbin/vyatta-qos.pl --delete-policy $VAR(@) +end: /opt/vyatta/sbin/vyatta-qos.pl --apply-policy $VAR(@) diff --git a/templates/qos-policy/traffic-limiter/node.tag/class/node.tag/bandwidth/node.def b/templates/qos-policy/traffic-limiter/node.tag/class/node.tag/bandwidth/node.def index 21a46a4..13c70ee 100644 --- a/templates/qos-policy/traffic-limiter/node.tag/class/node.tag/bandwidth/node.def +++ b/templates/qos-policy/traffic-limiter/node.tag/class/node.tag/bandwidth/node.def @@ -1,5 +1,5 @@ type: txt -help: Set the traffic-limit used for this class +help: Set the traffic-limit used for this class [REQUIRED] syntax:expression: exec "/opt/vyatta/sbin/vyatta-qos-util.pl --rate $VAR(@)" comp_help: Allowed values: <number> Bandwidth in Kbps diff --git a/templates/qos-policy/traffic-shaper/node.def b/templates/qos-policy/traffic-shaper/node.def index e54c093..cd7b07d 100644 --- a/templates/qos-policy/traffic-shaper/node.def +++ b/templates/qos-policy/traffic-shaper/node.def @@ -3,6 +3,6 @@ type: txt help: Set traffic shaping based policy syntax:expression: pattern $VAR(@) "^[[:alnum:]][-_[:alnum:]]*$" ; "only alpha-numeric policy name allowed" -create: /opt/vyatta/sbin/vyatta-qos.pl --create-policy "$VAR(.)" "$VAR(@)" -delete: /opt/vyatta/sbin/vyatta-qos.pl --delete-policy "$VAR(@)" -end: /opt/vyatta/sbin/vyatta-qos.pl --apply-policy "$VAR(@)" +create: /opt/vyatta/sbin/vyatta-qos.pl --create-policy $VAR(.) $VAR(@) +delete: /opt/vyatta/sbin/vyatta-qos.pl --delete-policy $VAR(@) +end: /opt/vyatta/sbin/vyatta-qos.pl --apply-policy $VAR(@) diff --git a/templates/qos-policy/traffic-shaper/node.tag/default/bandwidth/node.def b/templates/qos-policy/traffic-shaper/node.tag/default/bandwidth/node.def index 3743688..f0bc773 100644 --- a/templates/qos-policy/traffic-shaper/node.tag/default/bandwidth/node.def +++ b/templates/qos-policy/traffic-shaper/node.tag/default/bandwidth/node.def @@ -1,5 +1,5 @@ type: txt -help: Set the bandwidth used for default traffic +help: Set the bandwidth used for default traffic [REQUIRED] syntax:expression: exec "/opt/vyatta/sbin/vyatta-qos-util.pl --percent-or-rate \$VAR(@)" comp_help: Allowed values: <number> Bandwidth in Kbps per second |