From e7de8b95b1ba4e50abaa62013e84baa98ecdefa4 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 17 Nov 2010 15:12:47 -0800 Subject: Cleanup bridge port management Consolidate bridge port management into a single perl script. Done to fix the following bug. Bug 4745 Don't allow interface with address to be added to bridge. --- Makefile.am | 1 + scripts/vyatta-bridge.pl | 109 +++++++++++++++++++++ .../bonding/node.tag/bridge-group/node.def | 59 +---------- .../node.tag/vif/node.tag/bridge-group/node.def | 61 +----------- .../ethernet/node.tag/bridge-group/node.def | 61 +----------- .../node.tag/vif/node.tag/bridge-group/node.def | 63 +----------- 6 files changed, 114 insertions(+), 240 deletions(-) create mode 100644 scripts/vyatta-bridge.pl diff --git a/Makefile.am b/Makefile.am index f349121e..20312755 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-bridge.pl sbin_SCRIPTS += scripts/vyatta-bridgegroup-depedency.pl sbin_SCRIPTS += scripts/vyatta-dhcpv6-client.pl sbin_SCRIPTS += scripts/vyatta-update-grub.pl diff --git a/scripts/vyatta-bridge.pl b/scripts/vyatta-bridge.pl new file mode 100644 index 00000000..356361a2 --- /dev/null +++ b/scripts/vyatta-bridge.pl @@ -0,0 +1,109 @@ +#! /usr/bin/perl +# +# **** 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. +# +# A copy of the GNU General Public License is available as +# `/usr/share/common-licenses/GPL' in the Debian GNU/Linux distribution +# or on the World Wide Web at `http://www.gnu.org/copyleft/gpl.html'. +# You can also obtain it by writing to the Free Software Foundation, +# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301, USA. +# +# This code was originally developed by Vyatta, Inc. +# Portions created by Vyatta are Copyright (C) 2007 Vyatta, Inc. +# All Rights Reserved. +# +# Author: Stephen Hemminger +# Date: November 2010 +# Description: Script to setup bridge ports +# +# **** End License **** +# + +use strict; +use warnings; + +use lib "/opt/vyatta/share/perl5/"; +use Vyatta::Interface; +use Vyatta::Config; + +my $BRCTL = 'sudo /usr/sbin/brctl'; + +die "Usage: $0 ACTION ethX\n" unless ($#ARGV == 1); + +my ($action, $ifname) = @ARGV; + +# Get bridge information from configuration +my $intf = new Vyatta::Interface($ifname); +die "Unknown interface type $ifname\n" + unless $intf; + +my $cfg = new Vyatta::Config; +$cfg->setLevel($intf->path()); + +my $oldbridge = $cfg->returnOrigValue('bridge-group bridge'); +my $newbridge = $cfg->returnValue('bridge-group bridge'); +my $cost = $cfg->returnValue('bridge-group cost'); +my $priority = $cfg->returnValue('bridge-group priority'); + +if ( $action eq 'SET' ) { + die "Error: $ifname: not in a bridge-group.\n" unless $newbridge; + + my @address = $cfg->returnValues('address'); + die "Error: Can not add interface $ifname with addresses to bridge.\n" + if (@address); + + print "Adding interface $ifname to bridge $newbridge.\n"; + add_bridge_port($newbridge, $ifname, $cost, $priority); + +} elsif ( $action eq 'DELETE' ) { + die "Error: $ifname: not in a bridge-group.\n" unless $oldbridge; + + print "Removing interface $ifname from bridge $oldbridge.\n"; + remove_bridge_port($oldbridge, $ifname); + +} elsif ($oldbridge ne $newbridge) { + print "Moving interface $ifname from $oldbridge to $newbridge.\n"; + remove_bridge_port($oldbridge, $ifname); + add_bridge_port($newbridge, $ifname, $cost, $priority); +} + +exit 0; + +sub add_bridge_port { + my ($bridge, $port, $cost, $priority) = @_; + system("$BRCTL addif $bridge $port") == 0 + or exit 1; + + if ($cost) { + system ("$BRCTL setpathcost $bridge $port $cost") == 0 + or exit 1; + } + + if ($priority) { + system ("$BRCTL setportprio $bridge $port $priority") == 0 + or exit 1; + } +} + +sub remove_bridge_port { + my ($bridge, $port) = @_; + return unless $bridge; # not part of a bridge + + # 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 + return unless ( -d "/sys/class/net/$bridge" ); + + system ("$BRCTL delif $bridge $ifname") == 0 + or exit 1; +} diff --git a/templates/interfaces/bonding/node.tag/bridge-group/node.def b/templates/interfaces/bonding/node.tag/bridge-group/node.def index 9ce97b1b..778226a8 100644 --- a/templates/interfaces/bonding/node.tag/bridge-group/node.def +++ b/templates/interfaces/bonding/node.tag/bridge-group/node.def @@ -1,61 +1,4 @@ priority: 320 help: Add this interface to a bridge group -end: - bondif=$VAR(../@) - oldbridge=`/opt/vyatta/sbin/vyatta-cli-expand-var.pl \\$VAR\(/interfaces/bonding/$bondif/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." - /usr/sbin/brctl addif $newbridge $bondif; - - if [ -n "$VAR(./cost/@)" ]; then - /usr/sbin/brctl setpathcost $newbridge $bondif $VAR(./cost/@); - fi; - if [ -n "$VAR(./priority/@)" ]; then - /usr/sbin/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 - /usr/sbin/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 \ - /usr/sbin/brctl delif $oldbridge $bondif - fi - /usr/sbin/brctl addif $newbridge $bondif - fi - if [ -n "$VAR(./cost/@)" ]; then - /usr/sbin/brctl setpathcost $newbridge $bondif $VAR(./cost/@) - fi - if [ -n "$VAR(./priority/@)" ]; then - /usr/sbin/brctl setportprio $newbridge $bondif $VAR(./priority/@) - fi - fi - fi - exit 0 +end: /opt/vyatta/sbin/vyatta-bridge.pl ${COMMIT_ACTION} $VAR(../@) 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 7a4008ea..b603bb8c 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,63 +1,4 @@ priority: 325 # after vif and bridge 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." - /usr/sbin/brctl addif $newbridge $bondif; - - if [ -n "$VAR(./cost/@)" ]; then - /usr/sbin/brctl setpathcost $newbridge $bondif $VAR(./cost/@); - fi; - if [ -n "$VAR(./priority/@)" ]; then - /usr/sbin/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 - /usr/sbin/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 \ - /usr/sbin/brctl delif $oldbridge $bondif - fi - /usr/sbin/brctl addif $newbridge $bondif - fi - if [ -n "$VAR(./cost/@)" ]; then - /usr/sbin/brctl setpathcost $newbridge $bondif $VAR(./cost/@) - fi - if [ -n "$VAR(./priority/@)" ]; then - /usr/sbin/brctl setportprio $newbridge $bondif $VAR(./priority/@) - fi - fi - fi - exit 0 +end: /opt/vyatta/sbin/vyatta-bridge.pl ${COMMIT_ACTION} $VAR(../../@).$VAR(../@) diff --git a/templates/interfaces/ethernet/node.tag/bridge-group/node.def b/templates/interfaces/ethernet/node.tag/bridge-group/node.def index c56c31cc..74ecab4d 100644 --- a/templates/interfaces/ethernet/node.tag/bridge-group/node.def +++ b/templates/interfaces/ethernet/node.tag/bridge-group/node.def @@ -1,62 +1,3 @@ help: Add this interface to a bridge group -end: - ethif=$VAR(../@) - oldbridge=`/opt/vyatta/sbin/vyatta-cli-expand-var.pl \\$VAR\(/interfaces/ethernet/$ethif/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 $ethif to bridge $newbridge." - /usr/sbin/brctl addif $newbridge $ethif; - - if [ -n "$VAR(./cost/@)" ]; then - /usr/sbin/brctl setpathcost $newbridge $ethif $VAR(./cost/@); - fi; - if [ -n "$VAR(./priority/@)" ]; then - /usr/sbin/brctl setportprio $newbridge $ethif $VAR(./priority/@); - fi - fi - elif [ ${COMMIT_ACTION} = 'DELETE' ]; then - echo "Removing interface $ethif 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 - /usr/sbin/brctl delif $oldbridge $ethif - fi - else - if [ -z "$newbridge" ]; then - echo "Must specify bridge name." - exit 1 - else - if [ "$oldbridge" != "$newbridge" ]; then - echo "Removing interface $ethif 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 \ - /usr/sbin/brctl delif $oldbridge $ethif - fi - /usr/sbin/brctl addif $newbridge $ethif - fi - if [ -n "$VAR(./cost/@)" ]; then - /usr/sbin/brctl setpathcost $newbridge $ethif $VAR(./cost/@) - fi - if [ -n "$VAR(./priority/@)" ]; then - /usr/sbin/brctl setportprio $newbridge $ethif $VAR(./priority/@) - fi - fi - fi - exit 0 - - +end: /opt/vyatta/sbin/vyatta-bridge.pl ${COMMIT_ACTION} $VAR(../@) 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 84fa14f1..dfd046c2 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 @@ -1,65 +1,4 @@ priority: 320 help: Add this interface to a bridge group -end: - eth=$VAR(../../@) - vif=$VAR(../@) - ethif=$eth.$vif - oldbridge=`/opt/vyatta/sbin/vyatta-cli-expand-var.pl \\$VAR\(/interfaces/ethernet/$eth/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 $ethif to bridge $newbridge." - /usr/sbin/brctl addif $newbridge $ethif; - - if [ -n "$VAR(./cost/@)" ]; then - /usr/sbin/brctl setpathcost $newbridge $ethif $VAR(./cost/@); - fi; - if [ -n "$VAR(./priority/@)" ]; then - /usr/sbin/brctl setportprio $newbridge $ethif $VAR(./priority/@); - fi - fi - elif [ ${COMMIT_ACTION} = 'DELETE' ]; then - echo "Removing interface $ethif 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 - /usr/sbin/brctl delif $oldbridge $ethif - fi - else - if [ -z "$newbridge" ]; then - echo "Must specify bridge name." - exit 1 - else - if [ "$oldbridge" != "$newbridge" ]; then - echo "Removing interface $ethif 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 \ - /usr/sbin/brctl delif $oldbridge $ethif - fi - /usr/sbin/brctl addif $newbridge $ethif - fi - if [ -n "$VAR(./cost/@)" ]; then - /usr/sbin/brctl setpathcost $newbridge $ethif $VAR(./cost/@) - fi - if [ -n "$VAR(./priority/@)" ]; then - /usr/sbin/brctl setportprio $newbridge $ethif $VAR(./priority/@) - fi - fi - fi - exit 0 - - +end: /opt/vyatta/sbin/vyatta-bridge.pl ${COMMIT_ACTION} $VAR(../../@).$VAR(../@) -- cgit v1.2.3