summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2010-07-21 17:39:20 -0700
committerStephen Hemminger <stephen.hemminger@vyatta.com>2010-07-21 17:39:20 -0700
commita54e96671b8f5831e95886247d5076d612e072d2 (patch)
treecbc804a4676da411f1b6f33555fc70d260a6ecc2
parentec0e975fac476e805ba1ff7b8c25238bd492951c (diff)
downloadvyatta-cfg-qos-a54e96671b8f5831e95886247d5076d612e072d2.tar.gz
vyatta-cfg-qos-a54e96671b8f5831e95886247d5076d612e072d2.zip
Check target of redirect before removing ifb
Bug 5889 Deleting input interface not allowed if target of redirect
-rwxr-xr-xscripts/vyatta-qos.pl66
-rw-r--r--templates/interfaces/input/node.def6
2 files changed, 57 insertions, 15 deletions
diff --git a/scripts/vyatta-qos.pl b/scripts/vyatta-qos.pl
index 30d7c33..cb12354 100755
--- a/scripts/vyatta-qos.pl
+++ b/scripts/vyatta-qos.pl
@@ -36,7 +36,7 @@ my %policies = (
'priority-queue' => 'Priority',
'random-detect' => 'RandomDetect',
},
- 'in' => {
+ 'in' => {
'limiter' => 'TrafficLimiter',
}
);
@@ -119,7 +119,7 @@ sub delete_interface {
my $arg = $delcmd{$direction};
die "bad direction $direction\n" unless $arg;
-
+
my $cmd = "/sbin/tc qdisc del dev $interface ". $arg . " 2>/dev/null";
# ignore errors (may have no qdisc)
@@ -174,7 +174,7 @@ sub update_interface {
}
$shaper->commands( $device, $direction );
-
+
return if ($debug);
select STDOUT;
@@ -200,14 +200,14 @@ sub interfaces_using {
next unless $intf;
my $level = $intf->path() . ' traffic-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);
+ if ($cur eq $policy);
}
}
return @inuse;
@@ -220,7 +220,7 @@ sub delete_policy {
my @inuse = map { @$_[0] } interfaces_using($name);
die "Can not delete traffic-policy $name, still applied"
- . " to interface ", join(' ', @inuse), "\n"
+ . " to interface ", join(', ', @inuse), "\n"
if @inuse;
}
}
@@ -257,7 +257,7 @@ sub update_action {
apply_action($dev);
}
}
-
+
sub apply_action{
my $dev = shift;
my $interface = new Vyatta::Interface($dev);
@@ -274,7 +274,7 @@ sub apply_action{
foreach my $action (qw(mirror redirect)) {
my $target = $config->returnValue($action);
next unless $target;
-
+
# TODO support combination of limiting and redirect/mirror
die "interface $dev: combination of $action"
. " and traffic-policy $ingress not supported\n"
@@ -282,19 +282,19 @@ sub apply_action{
# Clear existing ingress
system("/sbin/tc qdisc del dev $dev parent ffff: 2>/dev/null");
-
+
system("/sbin/tc qdisc add dev $dev handle ffff: ingress") == 0
or die "tc qdisc ingress failed";
- my $cmd =
+ my $cmd =
"/sbin/tc filter add dev $dev parent ffff:"
- . " protocol all prio 10 u32"
+ . " protocol all prio 10 u32"
. " match u32 0 0 flowid 1:1"
. " action mirred egress $action dev $target";
system($cmd) == 0
or die "tc action $action command failed";
-
+
return;
}
@@ -303,6 +303,40 @@ sub apply_action{
unless($ingress);
}
+# find any interfaces whose actions refer to this interface
+sub interfaces_refer {
+ my $dev = shift;
+ my $config = new Vyatta::Config;
+ my @inuse = ();
+
+ foreach my $name ( getInterfaces() ) {
+ my $intf = new Vyatta::Interface($name);
+ next unless $intf;
+ $config->setLevel($intf->path());
+
+ foreach my $policy ( qw(redirect mirror) ) {
+ my $target = $config->returnValue($policy);
+ next unless $target;
+
+ if ($dev eq $target) {
+ push @inuse, $name;
+ last;
+ }
+ }
+ }
+
+ return @inuse;
+}
+
+sub check_target {
+ my $name= shift;
+ my @inuse = interfaces_refer ( $name );
+
+ die "Can not delete interface $name, still being used by:",
+ join(', ', @inuse), "\n" if @inuse;
+
+}
+
sub delete_action {
foreach my $dev (@_) {
system("/sbin/tc qdisc del dev $dev parent ffff: 2>/dev/null");
@@ -318,14 +352,16 @@ usage: vyatta-qos.pl --list-policy direction
vyatta-qos.pl --update-interface interface direction policy-name
vyatta-qos.pl --delete-interface interface direction
-
vyatta-qos.pl --start-interface interface
+
+ vyatta-qos.pl --update-action interface
+ vyatta-qos.pl --delete-action interface
EOF
exit 1;
}
my (@startList, @updateInterface, @deleteInterface);
-my ($updateAction, $deleteAction);
+my ($updateAction, $deleteAction, $checkTarget);
my ($listPolicy, @createPolicy, @applyPolicy, @deletePolicy);
GetOptions(
@@ -340,6 +376,7 @@ GetOptions(
"update-action=s" => \$updateAction,
"delete-action=s" => \$deleteAction,
+ "check-target=s" => \$checkTarget,
) or usage();
delete_interface(@deleteInterface) if ( @deleteInterface == 1);
@@ -353,3 +390,4 @@ apply_policy(@applyPolicy) if ( @applyPolicy );
update_action($updateAction) if ( $updateAction );
delete_action($deleteAction) if ( $deleteAction );
+check_target($checkTarget) if ( $checkTarget );
diff --git a/templates/interfaces/input/node.def b/templates/interfaces/input/node.def
index 06b00c9..945c6db 100644
--- a/templates/interfaces/input/node.def
+++ b/templates/interfaces/input/node.def
@@ -7,5 +7,9 @@ val_help: <ifbN>; Input functional block interface name
syntax:expression: pattern $VAR(@) "^ifb[0-9]+$" ; "name must be (ifb0-ifb999)"
begin: [ -d /sys/module/ifb ] || sudo modprobe ifb numifbs=0
+
create: ip link add $VAR(@) type ifb && ip link set $VAR(@) up
-delete: ip link delete dev $VAR(@)
+
+delete: [ -d /sys/class/net/$VAR(@) ] || exit 0
+ /opt/vyatta/sbin/vyatta-qos.pl --check-target $VAR(@) || exit 1
+ ip link delete dev $VAR(@)