diff options
author | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2008-07-15 14:13:51 -0700 |
---|---|---|
committer | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2008-07-15 14:13:51 -0700 |
commit | 81b51bb9270e77289604493761a2f7cb047bd3ea (patch) | |
tree | bc8c6d8cb285ea99ba8b4296b9b2a26b6bb4efea /scripts/vyatta-qos.pl | |
parent | 3dd93c5175de9a4d32cadb7bb0c4f832fb14312d (diff) | |
download | vyatta-cfg-qos-81b51bb9270e77289604493761a2f7cb047bd3ea.tar.gz vyatta-cfg-qos-81b51bb9270e77289604493761a2f7cb047bd3ea.zip |
Look for changes in QoS after commit
Since configuration system doesn't correctly notify on addition/deletion,
have to introduce this extra verbosity to have each traffic-shaper type
check for changes.
Bugfix for 3452
Diffstat (limited to 'scripts/vyatta-qos.pl')
-rwxr-xr-x | scripts/vyatta-qos.pl | 135 |
1 files changed, 107 insertions, 28 deletions
diff --git a/scripts/vyatta-qos.pl b/scripts/vyatta-qos.pl index ad97617..3d8e58b 100755 --- a/scripts/vyatta-qos.pl +++ b/scripts/vyatta-qos.pl @@ -21,24 +21,22 @@ use strict; use Getopt::Long; my $debug = $ENV{'QOS_DEBUG'}; -my $check = undef; +my ($check, $update, $applyChanges); my @updateInterface = (); my @deleteInterface = (); -my $listPolicy = undef; -my $deletePolicy = undef; +my ($listPolicy, $deletePolicy); my @createPolicy = (); -my @updatePolicy = (); GetOptions( "check" => \$check, + "apply-changes" => \$applyChanges, "update-interface=s{3}" => \@updateInterface, "delete-interface=s{2}" => \@deleteInterface, "list-policy" => \$listPolicy, "delete-policy=s" => \$deletePolicy, "create-policy=s{2}" => \@createPolicy, - "update-policy=s{2}" => \@updatePolicy, ); # class factory for policies @@ -135,19 +133,92 @@ sub update_interface { die "Unknown qos-policy $name\n"; } -sub delete_policy { +sub using_policy { + my ($config, $name, $interface) = @_; + my @inuse = (); + + foreach my $dir ( $config->listNodes("$interface qos-policy") ) { + my $policy = $config->returnValue("$interface qos-policy $dir"); + if ($policy eq $name) { + push @inuse, "$interface $dir"; + } + } + return @inuse; +} + +sub interfaces_using { my ($name) = @_; my $config = new VyattaConfig; + my @affected = (); + + $config->setLevel('interfaces'); + foreach my $type ( $config->listNodes() ) { + foreach my $interface ( $config->listNodes($type) ) { + push @affected, using_policy($config, $name, "$type $interface"); + + if ($type eq 'ethernet') { + foreach my $vif ( $config->listNodes("$type $interface vif") ) { + push @affected, using_policy($config, $name, "$type $interface vif $vif"); + } + } - $config->setLevel("interfaces ethernet"); - foreach my $interface ( $config->listNodes() ) { - foreach my $direction ( $config->listNodes("$interface qos-policy") ) { - if ($config->returnValue("$interface qos-policy $direction") eq $name) { - # can't delete active policy - die "Qos policy $name still in use on ethernet $interface $direction\n"; + if ($type eq 'adsl') { + foreach my $pvc ( $config->listNodes("adsl $interface pvc") ) { + foreach my $pvctype ( $config->listNodes("adsl $interface pvc $pvc") ) { + foreach my $vc ( $config->listNodes("adsl $interface pvc $pvc $pvctype") ) { + push @affected, using_policy($config, $name, + "adsl $interface pvc $pvc $pvctype $vc"); + } + } + } } } } + + return @affected; +} + +sub etherName { + my $eth = shift; + + if ($_ =~ /vif/) { + shift; + $eth .= $_; + } + return $eth; +} + +sub serialName { + my $wan = shift; + # XXX add vif + return $wan; +} + +sub adslName { + # adsl-name pvc pvc-num ppp-type id + my (undef, undef, undef, $type, $id) = @_; + + return $type . $id; +} + +# Handle mapping of interface types to device names +my %interfaceTypes = ( + 'ethernet' => \ðerName, + 'serial' => \&serialName, + 'adsl' => \&adslName, + ); + +sub delete_policy { + my ($name) = @_; + my @inuse = interfaces_using($name); + + if ( @inuse ) { + foreach my $usage (@inuse) { + warn "QoS policy $name used by $usage\n"; + } + # can't delete active policy + die "Must delete QoS policy from interfaces before deleting rules\n"; + } } sub check_conflict { @@ -172,18 +243,24 @@ sub create_policy { make_policy($config, $shaper, $name); } -sub update_policy { - my ($shaper, $name) = @_; +sub apply_changes { my $config = new VyattaConfig; - # Syntax check - make_policy($config, $shaper, $name); - - $config->setLevel("interfaces ethernet"); - foreach my $interface ( $config->listNodes() ) { - foreach my $direction ( $config->listNodes("$interface qos-policy") ) { - if ($config->returnValue("$interface qos-policy $direction") eq $name) { - update_interface($interface, $direction, $name); + $config->setLevel('qos-policy'); + foreach my $policy ($config->listNodes()) { + foreach my $name ($config->listNodes($policy)) { + my $shaper = make_policy($config, $policy, $name); + + if ($shaper->isChanged($name)) { + foreach my $cfgpath (interfaces_using($name)) { + my @elements = split / /, $cfgpath; + my $direction = pop @elements; # out, in, ... + my $type = shift @elements; # ethernet, serial, ... + my $interface = $interfaceTypes{$type}; + my $device = $interface->(@elements); + + update_interface($device, $direction, $name); + } } } } @@ -214,22 +291,24 @@ if ( $#createPolicy == 1) { exit 0; } -if ( $#updatePolicy == 1) { - update_policy(@updatePolicy); - exit 0; -} - if ( $deletePolicy ) { delete_policy($deletePolicy); exit 0; +} + +if ( $applyChanges ) { + apply_changes(); + exit 0; } print <<EOF; usage: vyatta-qos.pl --check vyatta-qos.pl --list-policy + vyatta-qos.pl --create-policy policy-type policy-name vyatta-qos.pl --delete-policy policy-name - vyatta-qos.pl --update-policy policy-type policy-name + vyatta-qos.pl --apply-changes policy-type policy-name + vyatta-qos.pl --update-interface interface direction policy-name vyatta-qos.pl --delete-interface interface direction |