diff options
author | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2010-11-17 15:12:47 -0800 |
---|---|---|
committer | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2010-11-17 20:29:03 -0800 |
commit | e7de8b95b1ba4e50abaa62013e84baa98ecdefa4 (patch) | |
tree | fb5abee6beff17e80d01170e17895187e5284bc2 /scripts | |
parent | 112158ad4b7e3a9c2a7060ca6d21e3fc519b53c6 (diff) | |
download | vyatta-cfg-quagga-e7de8b95b1ba4e50abaa62013e84baa98ecdefa4.tar.gz vyatta-cfg-quagga-e7de8b95b1ba4e50abaa62013e84baa98ecdefa4.zip |
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.
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/vyatta-bridge.pl | 109 |
1 files changed, 109 insertions, 0 deletions
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; +} |