diff options
24 files changed, 284 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index 0ab8017e..27152ff0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -33,6 +33,7 @@ sbin_SCRIPTS += scripts/mod_bootfile_eth_hwid sbin_SCRIPTS += scripts/dns-forwarding/vyatta-dns-forwarding.pl sbin_SCRIPTS += scripts/dynamic-dns/vyatta-dynamic-dns.pl sbin_SCRIPTS += scripts/vyatta-system-nameservers +sbin_SCRIPTS += scripts/vyatta-bonding.pl noinst_DATA = test_bootfile diff --git a/debian/control b/debian/control index 89b55bbe..7f732f2d 100644 --- a/debian/control +++ b/debian/control @@ -24,6 +24,7 @@ Depends: sed (>= 4.1.5), snmpd, vyatta-keepalived, bridge-utils, + ifenslave, ssh, ed, tshark, diff --git a/scripts/vyatta-bonding.pl b/scripts/vyatta-bonding.pl new file mode 100755 index 00000000..4e44d67b --- /dev/null +++ b/scripts/vyatta-bonding.pl @@ -0,0 +1,106 @@ +#!/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: September 2008 +# Description: Script to setup bonding interfaces +# +# **** End License **** +# + +use lib "/opt/vyatta/share/perl5/"; +use VyattaConfig; + +use Getopt::Long; +use strict; +use warnings; + +my %modes = ( + "round-robin" => 0, + "active-backup" => 1, + "xor-hash" => 2, + "broadcast" => 3, + "802.3ad" => 4, + "transmit-load-balance" => 5, + "adaptive-load-balance" => 6, +); + +sub create_bond { + my $bond = shift; + my $config = new VyattaConfig; + + $config->setLevel("interfaces bonding $bond"); + my $mode = $modes{$config->returnValue("mode")}; + defined $mode or die "bonding mode not defined"; + + system("sudo modprobe -o \"$bond\" bonding mode=$mode") == 0 + or die "modprobe of bonding failed: $!\n"; + + system("sudo ip link set \"$bond\" up") == 0 + or die "enabling $bond failed: $!\n"; + + $config->setLevel("interfaces ethernet"); + for my $intf ( $config->listNodes() ) { + my $group = $config->returnValue("bond-group"); + if (defined $group && $group eq $bond ) { + system("sudo ifenslave $bond $intf") == 0 + or die "Adding $intf to $bond failed\n"; + } + } +} + +sub delete_bond { + my $bond = shift; + system("sudo rmmod \"$bond\"") == 0 + or die "removal of bonding module failed: $!\n"; +} + +# See if bonding device exists and the mode has changed +sub change_bond { + my $bond = shift; + my $config = new VyattaConfig; + + $config->setLevel("interfaces bonding"); + if ( !( $config->isAdded($bond) || $config->isDeleted($bond) ) + && $config->isChanged("$bond mode") ) + { + delete_bond($bond); + create_bond($bond); + } + exit 0; +} + +sub usage { + print "Usage: $0 --create bondX\n"; + print " --delete bondX\n"; + print " --mode-change bondX\n"; + exit 1; +} + +GetOptions( + 'create=s' => sub { create_bond( $_[1] ); }, + 'delete=s' => sub { delete_bond( $_[1] ); }, + 'mode-change=s' => sub { change_bond( $_[1] ); }, +) or usage(); + + diff --git a/templates/interfaces/bonding/node.def b/templates/interfaces/bonding/node.def new file mode 100644 index 00000000..a0a56a8d --- /dev/null +++ b/templates/interfaces/bonding/node.def @@ -0,0 +1,9 @@ +tag: +type: txt +help: Set bonding interface +syntax:expression: pattern $VAR(@) "^bond[0-9]+$" \ + ; "bonding must be (bond0-bond99)" +create: ${vyatta_sbindir}/vyatta-bonding.pl --create $VAR(@) +delete: ${vyatta_sbindir}/vyatta-bonding.pl --delete $VAR(@) +end: ${vyatta_sbindir}/vyatta-bonding.pl --mode-change $VAR(@) +comp_help: Enter bond interface name (bond0 - bond99) diff --git a/templates/interfaces/bonding/node.tag/address/node.def b/templates/interfaces/bonding/node.tag/address/node.def new file mode 100644 index 00000000..d5237934 --- /dev/null +++ b/templates/interfaces/bonding/node.tag/address/node.def @@ -0,0 +1,12 @@ +multi: +type: txt +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(../@)" +update:expression: "sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-update $VAR(@) --dev $VAR(../@)"; "Error setting address $VAR(@) on interface $VAR(../@)" +delete:expression: "sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-delete $VAR(@) --dev $VAR(../@)"; "Error deleting address $VAR(@) on interface $VAR(../@)" +allowed: echo "dhcp <>" +comp_help:Possible completions: + <x.x.x.x/x> Set the IP address and prefix length + <h:h:h:h:h:h:h:h/x> Set the IPv6 address and prefix length + dhcp Set the IP address and prefix length via DHCP + diff --git a/templates/interfaces/bonding/node.tag/bridge-group/bridge/node.def b/templates/interfaces/bonding/node.tag/bridge-group/bridge/node.def new file mode 100644 index 00000000..79609a86 --- /dev/null +++ b/templates/interfaces/bonding/node.tag/bridge-group/bridge/node.def @@ -0,0 +1,11 @@ +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: echo $VAR(@) > /tmp/bridge-no.$PPID +allowed: local -a array ; + array=( /sys/class/net/br* ) ; + echo -n ${array[@]##*/} diff --git a/templates/interfaces/bonding/node.tag/bridge-group/cost/node.def b/templates/interfaces/bonding/node.tag/bridge-group/cost/node.def new file mode 100644 index 00000000..ef2d9940 --- /dev/null +++ b/templates/interfaces/bonding/node.tag/bridge-group/cost/node.def @@ -0,0 +1,4 @@ +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 new file mode 100644 index 00000000..fc3af5f5 --- /dev/null +++ b/templates/interfaces/bonding/node.tag/bridge-group/node.def @@ -0,0 +1,23 @@ +help: Add this interface to a bridge group + +create: sudo brctl addif $VAR(./bridge/@) $VAR(../@); + +delete: touch /tmp/bond-$VAR(../@)-bridge.$PPID; + +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; diff --git a/templates/interfaces/bonding/node.tag/bridge-group/priority/node.def b/templates/interfaces/bonding/node.tag/bridge-group/priority/node.def new file mode 100644 index 00000000..8688c394 --- /dev/null +++ b/templates/interfaces/bonding/node.tag/bridge-group/priority/node.def @@ -0,0 +1,4 @@ +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/description/node.def b/templates/interfaces/bonding/node.tag/description/node.def new file mode 100644 index 00000000..aeb40f0b --- /dev/null +++ b/templates/interfaces/bonding/node.tag/description/node.def @@ -0,0 +1,2 @@ +type: txt +help: Set description for this interface diff --git a/templates/interfaces/bonding/node.tag/disable/node.def b/templates/interfaces/bonding/node.tag/disable/node.def new file mode 100644 index 00000000..54090cc4 --- /dev/null +++ b/templates/interfaces/bonding/node.tag/disable/node.def @@ -0,0 +1,3 @@ +help: Set interface disabled +update:expression: "sudo ip link set $VAR(../@) down"; "Error disabling dev $VAR(../@)" +delete:expression: "sudo ip link set $VAR(../@) up"; "Error enabling dev $VAR(../@)" diff --git a/templates/interfaces/bonding/node.tag/mac/node.def b/templates/interfaces/bonding/node.tag/mac/node.def new file mode 100644 index 00000000..abafa7ab --- /dev/null +++ b/templates/interfaces/bonding/node.tag/mac/node.def @@ -0,0 +1,7 @@ +type: macaddr +help: Set the Media Access Control (MAC) address of this interface +syntax:expression: exec "\ + /opt/vyatta/sbin/vyatta-interfaces.pl --dev $VAR(../@) --valid-mac $VAR(@)" +update: /opt/vyatta/sbin/vyatta-interfaces.pl --dev $VAR(../@) --set-mac $VAR(@) +delete: /opt/vyatta/sbin/vyatta-interfaces.pl --dev $VAR(../@) --set-mac $VAR(../hw-id/@) + diff --git a/templates/interfaces/bonding/node.tag/mode/node.def b/templates/interfaces/bonding/node.tag/mode/node.def new file mode 100644 index 00000000..a059f615 --- /dev/null +++ b/templates/interfaces/bonding/node.tag/mode/node.def @@ -0,0 +1,14 @@ +type: txt +default: "802.3ad" +syntax:expression: $VAR(@) in \ + "round-robin", "active-backup", "xor-hash","broadcast","802.3ad", \ + "transmit-load-balance", "adaptive-load-balance" +help: Sets the bonding mode +comp_help: Possible bonding mode +802.3ad IEEE 802.3ad Dynamic link aggregation (Default) +active-backup Active-backup policy: Only one slave in the bond is active +balance-alb Adaptive load balancing based on transmit and receive +balance-rr Round-robin policy: Transmit packets in sequential order +balance-tlb Adaptive transmit load balancing based on transmit speed +balance-xor XOR policy: Transmit based on the selected transmit hash policy +broadcast Broadcast policy: transmits everything on all slave interfaces diff --git a/templates/interfaces/bonding/node.tag/mtu/node.def b/templates/interfaces/bonding/node.tag/mtu/node.def new file mode 100644 index 00000000..07c102ac --- /dev/null +++ b/templates/interfaces/bonding/node.tag/mtu/node.def @@ -0,0 +1,5 @@ +type: u32 +help: Set the Maximum Transmission Unit (MTU) for this interface +syntax:expression: $VAR(@) >= 68 && $VAR(@) <= 9000; "MTU must be between 68 and 9000" +update:expression: "sudo ip link set $VAR(../@) mtu $VAR(@)"; "Error setting MTU on dev $VAR(../@)" +delete:expression: "sudo ip link set $VAR(../@) mtu 1500"; "Error deleting MTU on dev $VAR(../@)" diff --git a/templates/interfaces/bonding/node.tag/primary/node.def b/templates/interfaces/bonding/node.tag/primary/node.def new file mode 100644 index 00000000..171c8daf --- /dev/null +++ b/templates/interfaces/bonding/node.tag/primary/node.def @@ -0,0 +1,12 @@ +type: txt +syntax:expression: exec \ + "grep -s $VAR(@) /sys/class/net/$VAR(../@)/bonding/slaves" \ + ; "Ethernet interface must be part of the bonding group" +allowed: cat /sys/class/net/$VAR(../@)/bonding/slaves +update: sudo sh -c "echo $VAR(@) >/sys/class/net/$VAR(../@)/bonding/primary" +help: Specify the primary device + + + + + diff --git a/templates/interfaces/bonding/node.tag/vif/node.def b/templates/interfaces/bonding/node.tag/vif/node.def new file mode 100644 index 00000000..d37b045e --- /dev/null +++ b/templates/interfaces/bonding/node.tag/vif/node.def @@ -0,0 +1,12 @@ +tag: +type: u32 +help: Set Virtual Local Area Network (VLAN) ID +syntax:expression: $VAR(@) >= 0 && $VAR(@) <= 4094; "VLAN ID must be between 0 and 4094" +create: sudo modprobe 8021q + sudo vconfig add "$VAR(../@)" "$VAR(@)" + sudo ip link set "$VAR(../@).$VAR(@)" up + vyatta-vtysh -c "configure terminal" \ + -c "interface $VAR(../@).$VAR(@)" -c "link-detect" +delete: sudo vconfig rem "$VAR(../@).$VAR(@)" +comp_help: possible completions: + <0-4094> Set VLAN ID diff --git a/templates/interfaces/bonding/node.tag/vif/node.tag/address/node.def b/templates/interfaces/bonding/node.tag/vif/node.tag/address/node.def new file mode 100644 index 00000000..625130af --- /dev/null +++ b/templates/interfaces/bonding/node.tag/vif/node.tag/address/node.def @@ -0,0 +1,11 @@ +multi: +type: txt +help: Set an IP address for this interface +syntax:expression: exec "/opt/vyatta/sbin/vyatta-interfaces.pl --valid-addr $VAR(@) --dev $VAR(../../@).$VAR(../@) "; "Invalid IP address/prefix [$VAR(@)] for interface $VAR(../../@).$VAR(../@)" +create:expression: "sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-update $VAR(@) --dev $VAR(../../@).$VAR(../@) "; "Error setting address $VAR(@) on dev $VAR(../../@).$VAR(../@) " +delete:expression: "sudo /opt/vyatta/sbin/vyatta-interfaces.pl --eth-addr-delete $VAR(@) --dev $VAR(../../@).$VAR(../@) "; "Error deleting address $VAR(@) on dev $VAR(../../@).$VAR(../@) " +allowed: echo "dhcp <>" +comp_help:Possible completions: + <x.x.x.x/x> Set the IP address and prefix length + <h:h:h:h:h:h:h:h/x> Set the IPv6 address and prefix length + dhcp Set the IP address and prefix length via DHCP 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 new file mode 100644 index 00000000..e3674bcd --- /dev/null +++ b/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/bridge/node.def @@ -0,0 +1,11 @@ +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[@]##*/} 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 new file mode 100644 index 00000000..ef2d9940 --- /dev/null +++ b/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/cost/node.def @@ -0,0 +1,4 @@ +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 new file mode 100644 index 00000000..3e93d112 --- /dev/null +++ b/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/node.def @@ -0,0 +1,14 @@ +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 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 new file mode 100644 index 00000000..8688c394 --- /dev/null +++ b/templates/interfaces/bonding/node.tag/vif/node.tag/bridge-group/priority/node.def @@ -0,0 +1,4 @@ +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/description/node.def b/templates/interfaces/bonding/node.tag/vif/node.tag/description/node.def new file mode 100644 index 00000000..aeb40f0b --- /dev/null +++ b/templates/interfaces/bonding/node.tag/vif/node.tag/description/node.def @@ -0,0 +1,2 @@ +type: txt +help: Set description for this interface diff --git a/templates/interfaces/bonding/node.tag/vif/node.tag/disable/node.def b/templates/interfaces/bonding/node.tag/vif/node.tag/disable/node.def new file mode 100644 index 00000000..66efddcc --- /dev/null +++ b/templates/interfaces/bonding/node.tag/vif/node.tag/disable/node.def @@ -0,0 +1,3 @@ +help: Set interface disabled +update:sudo ip link set $VAR(../../@).$VAR(../@) down +delete:sudo ip link set $VAR(../../@).$VAR(../@) up diff --git a/templates/interfaces/ethernet/node.tag/bond-group/node.def b/templates/interfaces/ethernet/node.tag/bond-group/node.def new file mode 100644 index 00000000..e62e37ab --- /dev/null +++ b/templates/interfaces/ethernet/node.tag/bond-group/node.def @@ -0,0 +1,9 @@ +type: txt +help: Add this interface to a bonding group +create: sudo ifenslave $VAR(@) $VAR(../@) +delete: sudo ifenslave -d $VAR(@) $VAR(../@) +allowed: for dev in /sys/class/net/* + do if [[ -d $dev/bonding ]] + then echo -n ${dev##*/} " " + fi + done |