diff options
14 files changed, 279 insertions, 52 deletions
diff --git a/Makefile.am b/Makefile.am index d77f02dc..ac8374a3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -55,6 +55,7 @@ sbin_SCRIPTS += scripts/install/install-image-new sbin_SCRIPTS += scripts/install/install-image-existing sbin_SCRIPTS += scripts/install/install-postinst-new sbin_SCRIPTS += scripts/install/install-image +sbin_SCRIPTS += scripts/vyatta-bridgegroup-depedency.pl share_perl5_DATA = lib/Vyatta/Login/User.pm share_perl5_DATA += lib/Vyatta/Login/RadiusServer.pm diff --git a/scripts/vyatta-bridgegroup-depedency.pl b/scripts/vyatta-bridgegroup-depedency.pl new file mode 100644 index 00000000..03d92ed0 --- /dev/null +++ b/scripts/vyatta-bridgegroup-depedency.pl @@ -0,0 +1,91 @@ +#!/usr/bin/perl +# +# Module: vyatta-bridgegroup-dependency.pl +# +# **** License **** +# 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) 2010 Vyatta, Inc. +# All Rights Reserved. +# +# Author: Mohit Mehta +# Date: February 2010 +# Description: To check dependency between bridge and interfaces assigned to it +# +# **** End License **** +# + +use lib "/opt/vyatta/share/perl5/"; +use Vyatta::Config; +use Vyatta::Misc; +use Getopt::Long; +use POSIX; + +use strict; +use warnings; + +sub check_bridge_interfaces { + my $bridge_intf = shift; + foreach my $name ( Vyatta::Misc::getInterfaces() ) { + my $intf = new Vyatta::Interface($name); + next unless $intf; + my $intf_bridge = undef; + $intf_bridge = $intf->bridge_grp(); + if (defined $intf_bridge && $intf_bridge eq $bridge_intf) { + return "Interfaces are still assigned to bridge $bridge_intf"; + } + } + return; +} + +sub is_bridge_deleted { + my $bridge_name = shift; + my $config = new Vyatta::Config; + my @bridge_intfs = $config->listNodes("interfaces bridge"); + my @orig_bridge_intfs = $config->listOrigNodes("interfaces bridge"); + if (scalar(grep(/^$bridge_name$/, @bridge_intfs)) == 0) { + if (scalar(grep(/^$bridge_name$/, @orig_bridge_intfs)) > 0) { + # bridge deleted in proposed config + return; + } + } + exit 1; +} + +# +# main +# + +my ($error, $warning); +my ($no_interfaces_assigned, $bridge_interface, $bridge_notin_proposedcfg); + +GetOptions( "no-interfaces-assigned!" => \$no_interfaces_assigned, + "bridge-interface=s" => \$bridge_interface, + "bridge-notin-proposedcfg!" => \$bridge_notin_proposedcfg); + +die "undefined bridge interface" if ! defined $bridge_interface; + +($error, $warning) = check_bridge_interfaces($bridge_interface) + if ($no_interfaces_assigned); + +($error, $warning) = is_bridge_deleted($bridge_interface) + if ($bridge_notin_proposedcfg); + +if (defined $warning) { + print "$warning\n"; +} + +if (defined $error) { + print "$error\n"; + exit 1; +} + +exit 0; diff --git a/templates/interfaces/bonding/node.tag/bridge-group/bridge/node.def b/templates/interfaces/bonding/node.tag/bridge-group/bridge/node.def index dc958dd5..bf4d0f7f 100644 --- a/templates/interfaces/bonding/node.tag/bridge-group/bridge/node.def +++ b/templates/interfaces/bonding/node.tag/bridge-group/bridge/node.def @@ -1,6 +1,8 @@ type: txt + help: Set this interface to a bridge-group + commit:expression: exec \ "/opt/vyatta/sbin/vyatta-interfaces.pl --dev=$VAR(@) --check=bridge" -delete: echo $VAR(@) > /tmp/bridge-no.$PPID + allowed: /opt/vyatta/sbin/vyatta-interfaces.pl --show=bridge diff --git a/templates/interfaces/bonding/node.tag/bridge-group/cost/node.def b/templates/interfaces/bonding/node.tag/bridge-group/cost/node.def index ef2d9940..f90f4769 100644 --- a/templates/interfaces/bonding/node.tag/bridge-group/cost/node.def +++ b/templates/interfaces/bonding/node.tag/bridge-group/cost/node.def @@ -1,4 +1,6 @@ type: u32 + help: Set the path cost for this port + comp_help: possible completions: <0-2147483647> Set port cost diff --git a/templates/interfaces/bonding/node.tag/bridge-group/node.def b/templates/interfaces/bonding/node.tag/bridge-group/node.def index dc82ec7a..940295fa 100644 --- a/templates/interfaces/bonding/node.tag/bridge-group/node.def +++ b/templates/interfaces/bonding/node.tag/bridge-group/node.def @@ -1,24 +1,61 @@ priority: 320 help: Add this interface to a bridge group -create: sudo brctl addif $VAR(./bridge/@) $VAR(../@); +end: + bondif=$VAR(../@) + oldbridge=`/opt/vyatta/sbin/vyatta-cli-expand-var.pl \\$VAR\(/interfaces/bonding/$bondif/bridge-group/bridge/@\)` + newbridge="$VAR(./bridge/@)" -delete: touch /tmp/bond-$VAR(../@)-bridge.$PPID; + if [ ${COMMIT_ACTION} = 'SET' ]; then + if [ -z "$newbridge" ]; then + echo "Must specify bridge name." + exit 1 + else + echo "Adding interface $bondif to bridge $newbridge." + sudo brctl addif $newbridge $bondif; -end: if [ -f "/tmp/bond-$VAR(../@)-bridge.$PPID" ]; then - rm -f /tmp/bond-$VAR(../@)-bridge.$PPID; - brno=$(cat /tmp/bridge-no.$PPID); - sudo brctl delif $brno $VAR(../@); - rm -f /tmp/bridge-no.$PPID; - else - if [ -z "$VAR(./bridge/@)" ]; then - echo "Must set the bridge interface"; - exit 1; - fi; - if [ -n "$VAR(./cost/@)" ]; then - sudo brctl setpathcost $VAR(./bridge/@) $VAR(../@) $VAR(./cost/@); - fi; - if [ -n "$VAR(./priority/@)" ]; then - sudo brctl setportprio $VAR(./bridge/@) $VAR(../@) $VAR(./priority/@); - fi; - fi; + if [ -n "$VAR(./cost/@)" ]; then + sudo brctl setpathcost $newbridge $bondif $VAR(./cost/@); + fi; + if [ -n "$VAR(./priority/@)" ]; then + sudo brctl setportprio $newbridge $bondif $VAR(./priority/@); + fi + fi + elif [ ${COMMIT_ACTION} = 'DELETE' ]; then + echo "Removing interface $bondif from bridge $oldbridge." + if /opt/vyatta/sbin/vyatta-bridgegroup-depedency.pl \ + --bridge-notin-proposedcfg \ + --bridge-interface="$oldbridge"; then \ + # this is the case where the bridge that this interface is assigned + # to is getting deleted in the same commit as the bridge node under + # this interface - Bug 5064|4734. Since bridge has a higher priority; + # it gets deleted before the removal of bridge-groups under interfaces + exit 0 + else + sudo brctl delif $oldbridge $bondif + fi + else + if [ -z "$newbridge" ]; then + echo "Must specify bridge name." + exit 1 + else + if [ "$oldbridge" != "$newbridge" ]; then + echo "Removing interface $bondif from bridge $oldbridge and adding it to $newbridge." + # do not remove interface from bridge if bridge not in proposed config + # reason is same as mentioned in the ${COMMIT_ACTION} = 'DELETE' section + if ! /opt/vyatta/sbin/vyatta-bridgegroup-depedency.pl \ + --bridge-notin-proposedcfg \ + --bridge-interface="$oldbridge"; then \ + sudo brctl delif $oldbridge $bondif + fi + sudo brctl addif $newbridge $bondif + fi + if [ -n "$VAR(./cost/@)" ]; then + sudo brctl setpathcost $newbridge $bondif $VAR(./cost/@) + fi + if [ -n "$VAR(./priority/@)" ]; then + sudo brctl setportprio $newbridge $bondif $VAR(./priority/@) + fi + fi + fi + exit 0 diff --git a/templates/interfaces/bonding/node.tag/bridge-group/priority/node.def b/templates/interfaces/bonding/node.tag/bridge-group/priority/node.def index 8688c394..5c11ec4f 100644 --- a/templates/interfaces/bonding/node.tag/bridge-group/priority/node.def +++ b/templates/interfaces/bonding/node.tag/bridge-group/priority/node.def @@ -1,4 +1,6 @@ type: u32 + help: Set the path priority for this port + comp_help: possible completions: <0-255> Set port priority diff --git a/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/bridge/node.def b/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/bridge/node.def index e3674bcd..4e3e22ec 100644 --- a/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/bridge/node.def +++ b/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/bridge/node.def @@ -1,11 +1,8 @@ type: txt + help: Set this interface to a bridge-group -syntax:expression: exec " \ - if [ -z \"`sudo brctl show | grep $VAR(@) `\" ]; then \ - echo bridge interface $VAR(@) doesn\\'t exist on this system ; \ - exit 1 ; \ - fi ; " -delete:expression: "sudo brctl delif $VAR(@) $VAR(../../../@).$VAR(../../@)" -allowed: local -a array ; - array=( /sys/class/net/br* ) ; - echo -n ${array[@]##*/} + +commit:expression: exec \ + "/opt/vyatta/sbin/vyatta-interfaces.pl --dev=$VAR(@) --check=bridge" + +allowed: /opt/vyatta/sbin/vyatta-interfaces.pl --show=bridge diff --git a/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/cost/node.def b/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/cost/node.def index ef2d9940..f90f4769 100644 --- a/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/cost/node.def +++ b/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/cost/node.def @@ -1,4 +1,6 @@ type: u32 + help: Set the path cost for this port + comp_help: possible completions: <0-2147483647> Set port cost diff --git a/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/node.def b/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/node.def index 3e93d112..04dc957b 100644 --- a/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/node.def +++ b/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/node.def @@ -1,14 +1,62 @@ -help: Set this interface to a bridge group -commit:expression: $VAR(./bridge/) != ""; "Must set the bridge interface" -create:sudo brctl addif $VAR(./bridge/@) $VAR(../../@).$VAR(../@) -delete:touch /tmp/bond-$VAR(../@)-bridge.$PPID -end: if [ -f "/tmp/bond-$VAR(../@)-bridge.$PPID" ]; then - rm -f "/tmp/bond-$VAR(../@)-bridge.$PPID" - else - if [ -n "$VAR(./cost/@)" ]; then - sudo brctl setpathcost $VAR(./bridge/@) "$VAR(../../@).$VAR(../@)" "$VAR(./cost/@)" - fi - if [ -n "$VAR(./priority/@)" ]; then - sudo brctl setportprio $VAR(./bridge/@) "$VAR(../../@).$VAR(../@)" "$VAR(./priority/@)" - fi - fi +help: Add this interface to a bridge group + +end: + bond=$VAR(../../@) + vif=$VAR(../@) + bondif=$bond.$vif + oldbridge=`/opt/vyatta/sbin/vyatta-cli-expand-var.pl \\$VAR\(/interfaces/bonding/$bond/vif/$vif/bridge-group/bridge/@\)` + newbridge="$VAR(./bridge/@)" + + if [ ${COMMIT_ACTION} = 'SET' ]; then + if [ -z "$newbridge" ]; then + echo "Must specify bridge name." + exit 1 + else + echo "Adding interface $bondif to bridge $newbridge." + sudo brctl addif $newbridge $bondif; + + if [ -n "$VAR(./cost/@)" ]; then + sudo brctl setpathcost $newbridge $bondif $VAR(./cost/@); + fi; + if [ -n "$VAR(./priority/@)" ]; then + sudo brctl setportprio $newbridge $bondif $VAR(./priority/@); + fi + fi + elif [ ${COMMIT_ACTION} = 'DELETE' ]; then + echo "Removing interface $bondif from bridge $oldbridge." + if /opt/vyatta/sbin/vyatta-bridgegroup-depedency.pl \ + --bridge-notin-proposedcfg \ + --bridge-interface="$oldbridge"; then \ + # this is the case where the bridge that this interface is assigned + # to is getting deleted in the same commit as the bridge node under + # this interface - Bug 5064|4734. Since bridge has a higher priority; + # it gets deleted before the removal of bridge-groups under interfaces + exit 0 + else + sudo brctl delif $oldbridge $bondif + fi + else + if [ -z "$newbridge" ]; then + echo "Must specify bridge name." + exit 1 + else + if [ "$oldbridge" != "$newbridge" ]; then + echo "Removing interface $bondif from bridge $oldbridge and adding it to $newbridge." + # do not remove interface from bridge if bridge not in proposed config + # reason is same as mentioned in the ${COMMIT_ACTION} = 'DELETE' section + if ! /opt/vyatta/sbin/vyatta-bridgegroup-depedency.pl \ + --bridge-notin-proposedcfg \ + --bridge-interface="$oldbridge"; then \ + sudo brctl delif $oldbridge $bondif + fi + sudo brctl addif $newbridge $bondif + fi + if [ -n "$VAR(./cost/@)" ]; then + sudo brctl setpathcost $newbridge $bondif $VAR(./cost/@) + fi + if [ -n "$VAR(./priority/@)" ]; then + sudo brctl setportprio $newbridge $bondif $VAR(./priority/@) + fi + fi + fi + exit 0 diff --git a/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/priority/node.def b/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/priority/node.def index 8688c394..5c11ec4f 100644 --- a/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/priority/node.def +++ b/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/priority/node.def @@ -1,4 +1,6 @@ type: u32 + help: Set the path priority for this port + comp_help: possible completions: <0-255> Set port priority diff --git a/templates/interfaces/bridge/node.def b/templates/interfaces/bridge/node.def index a7d82012..55c961ba 100644 --- a/templates/interfaces/bridge/node.def +++ b/templates/interfaces/bridge/node.def @@ -8,10 +8,11 @@ syntax:expression: pattern $VAR(@) "^br[0-9]+$" ; "Must be (br0 - br999)" create: sudo brctl addbr $VAR(@) sudo ip link set $VAR(@) up -delete: if [ -n "`ls /sys/class/net/$VAR(@)/brif`" ]; then - echo "Interfaces are still assigned to bridge $VAR(@)"; - exit 1; - fi; +delete: if ! /opt/vyatta/sbin/vyatta-bridgegroup-depedency.pl \ + --no-interfaces-assigned \ + --bridge-interface="$VAR(@)"; then \ + exit 1 + fi sudo ip link set $VAR(@) down; sudo brctl delbr $VAR(@); diff --git a/templates/interfaces/bridge/node.tag/address/node.def b/templates/interfaces/bridge/node.tag/address/node.def index 0c4ba0bd..7278df30 100644 --- a/templates/interfaces/bridge/node.tag/address/node.def +++ b/templates/interfaces/bridge/node.tag/address/node.def @@ -5,7 +5,17 @@ help: Set an IP address for this interface syntax:expression: exec "/opt/vyatta/sbin/vyatta-interfaces.pl --valid-addr $VAR(@) --dev $VAR(../@)";\ "Invalid IP address/prefix [$VAR(@)] for interface $VAR(../@)" create: sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-update $VAR(@) --dev $VAR(../@) -delete: sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-delete $VAR(@) --dev $VAR(../@) +delete: + if /opt/vyatta/sbin/vyatta-bridgegroup-depedency.pl \ + --bridge-notin-proposedcfg \ + --bridge-interface="$VAR(../@)"; then \ + # bridge has higher priority than bridge-address so bridge gets deleted + # before bridge-address in case the whole of bridge config was deleted. + # In that case we do not need to delete address here now + exit 0 + else + sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-delete $VAR(@) --dev $VAR(../@) + fi allowed: echo "dhcp <>" comp_help:Possible completions: <x.x.x.x/x> Set the IP address and prefix length diff --git a/templates/interfaces/ethernet/node.tag/bridge-group/node.def b/templates/interfaces/ethernet/node.tag/bridge-group/node.def index b30a9e10..7590dc96 100644 --- a/templates/interfaces/ethernet/node.tag/bridge-group/node.def +++ b/templates/interfaces/ethernet/node.tag/bridge-group/node.def @@ -22,7 +22,17 @@ end: fi elif [ ${COMMIT_ACTION} = 'DELETE' ]; then echo "Removing interface $ethif from bridge $oldbridge." - sudo brctl delif $oldbridge $ethif + if /opt/vyatta/sbin/vyatta-bridgegroup-depedency.pl \ + --bridge-notin-proposedcfg \ + --bridge-interface="$oldbridge"; then \ + # this is the case where the bridge that this interface is assigned + # to is getting deleted in the same commit as the bridge node under + # this interface - Bug 5064|4734. Since bridge has a higher priority; + # it gets deleted before the removal of bridge-groups under interfaces + exit 0 + else + sudo brctl delif $oldbridge $ethif + fi else if [ -z "$newbridge" ]; then echo "Must specify bridge name." @@ -30,7 +40,13 @@ end: else if [ "$oldbridge" != "$newbridge" ]; then echo "Removing interface $ethif from bridge $oldbridge and adding it to $newbridge." - sudo brctl delif $oldbridge $ethif + # do not remove interface from bridge if bridge not in proposed config + # reason is same as mentioned in the ${COMMIT_ACTION} = 'DELETE' section + if ! /opt/vyatta/sbin/vyatta-bridgegroup-depedency.pl \ + --bridge-notin-proposedcfg \ + --bridge-interface="$oldbridge"; then \ + sudo brctl delif $oldbridge $ethif + fi sudo brctl addif $newbridge $ethif fi if [ -n "$VAR(./cost/@)" ]; then diff --git a/templates/interfaces/ethernet/node.tag/vif/node.tag/bridge-group/node.def b/templates/interfaces/ethernet/node.tag/vif/node.tag/bridge-group/node.def index e3645b1c..dd3863a0 100644 --- a/templates/interfaces/ethernet/node.tag/vif/node.tag/bridge-group/node.def +++ b/templates/interfaces/ethernet/node.tag/vif/node.tag/bridge-group/node.def @@ -25,7 +25,17 @@ end: fi elif [ ${COMMIT_ACTION} = 'DELETE' ]; then echo "Removing interface $ethif from bridge $oldbridge." - sudo brctl delif $oldbridge $ethif + if /opt/vyatta/sbin/vyatta-bridgegroup-depedency.pl \ + --bridge-notin-proposedcfg \ + --bridge-interface="$oldbridge"; then \ + # this is the case where the bridge that this interface is assigned + # to is getting deleted in the same commit as the bridge node under + # this interface - Bug 5064|4734. Since bridge has a higher priority; + # it gets deleted before the removal of bridge-groups under interfaces + exit 0 + else + sudo brctl delif $oldbridge $ethif + fi else if [ -z "$newbridge" ]; then echo "Must specify bridge name." @@ -33,7 +43,13 @@ end: else if [ "$oldbridge" != "$newbridge" ]; then echo "Removing interface $ethif from bridge $oldbridge and adding it to $newbridge." - sudo brctl delif $oldbridge $ethif + # do not remove interface from bridge if bridge not in proposed config + # reason is same as mentioned in the ${COMMIT_ACTION} = 'DELETE' section + if ! /opt/vyatta/sbin/vyatta-bridgegroup-depedency.pl \ + --bridge-notin-proposedcfg \ + --bridge-interface="$oldbridge"; then \ + sudo brctl delif $oldbridge $ethif + fi sudo brctl addif $newbridge $ethif fi if [ -n "$VAR(./cost/@)" ]; then |