From 8fd020858ef23a092d0b97ec992df18a08de6232 Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Fri, 24 Aug 2012 16:18:22 -0700 Subject: [PATCH] Bonding support on CentOS / Redhat --- net/CHANGELOG | 2 ++ net/edit_bifc.cgi | 11 +++++- net/lang/en | 5 ++- net/linux-lib.pl | 6 ++-- net/redhat-linux-lib.pl | 75 +++++++++++++++++++++++++++++++++++++++++ net/save_bifc.cgi | 6 ++++ 6 files changed, 101 insertions(+), 4 deletions(-) diff --git a/net/CHANGELOG b/net/CHANGELOG index f23d79589..640421a94 100644 --- a/net/CHANGELOG +++ b/net/CHANGELOG @@ -64,3 +64,5 @@ On Debian, Ubuntu, Redhat, CentOS and Fedora systems boot-time network interface If Postfix is installed when the hostname is changed, the mydestination (local hostname) configuration parameter is updated too. ---- Changes since 1.580 ---- Allowed the MTU to be set at boot time on Debian Linux, and fixed bugs editing VLANs, thanks to a patch from Caspar Smit. +---- Changes since 1.590 ---- +Bonding interfaces can now be created on CentOS, Redhat and Fedora Linuxes, thanks to a patch from Caspar Smit. diff --git a/net/edit_bifc.cgi b/net/edit_bifc.cgi index 10ee32c89..77bb568c8 100755 --- a/net/edit_bifc.cgi +++ b/net/edit_bifc.cgi @@ -11,6 +11,12 @@ require './net-lib.pl'; if ($in{'new'} && $in{'bond'}) { # New bonding interface &ui_print_header(undef, $text{'bonding_create'}, ""); + $bmax = -1; + foreach $b (@boot) { + if ($b->{'fullname'} =~ /^bond(\d+)$/) { + $bmax = $1; + } + } } elsif ($in{'new'} && $in{'vlan'}) { # New VLAN @@ -82,6 +88,9 @@ elsif ($in{'new'}) { elsif ($in{'bridge'}) { $namefield = "br ".&ui_textbox("name", ($bmax+1), 3); } + elsif ($in{'bond'}) { + $namefield = "bond ".&ui_textbox("name", ($bmax+1), 3); + } else { $namefield = &ui_textbox("name", undef, 6); } @@ -225,7 +234,7 @@ if ($b && $b->{'virtual'} eq "") { if ($in{'bond'} || &iface_type($b->{'name'}) eq 'Bonded') { # Select bonding teampartner print &ui_table_row($text{'bonding_teamparts'}, - &ui_textbox("partner", $b->{'partner'}, 10)); + &ui_textbox("partner", $b->{'partner'}, 10)." ".$text{'bonding_teampartsdesc'}); # Select teaming mode @mode = ("balance-rr", "activebackup", "balance-xor", "broadcast", "802.3ad", "balance-tlb", "balance-alb"); diff --git a/net/lang/en b/net/lang/en index 5a6ec1489..798cd9d1a 100644 --- a/net/lang/en +++ b/net/lang/en @@ -107,10 +107,13 @@ bifc_edhcpmain=DHCP can only be enabled on the primary network interface bifc_bridgeto=Connect bridge to interface bifc_ebridgeto=An existing Ethernet interface must be selected for this bridge to use bifc_ebridgeto2=The selected interface for the bridge must not have any address assigned +bifc_ebridge=Bridge interface must be a number +bifc_ebond=Bond interface must be a number bonding_add=Add a new bonding Interface. bonding_create=Create Bonding Interface -bonding_teamparts=Teaming Partner +bonding_teamparts=Teaming Partners +bonding_teampartsdesc=Seperate partners with whitespaces e.g. "eth2 eth4" bonding_teammode=Teaming Mode bonding_miimon=Mii-Monitoring Interval bonding_updelay=Updelay diff --git a/net/linux-lib.pl b/net/linux-lib.pl index 6df930a1f..1780547da 100755 --- a/net/linux-lib.pl +++ b/net/linux-lib.pl @@ -187,8 +187,10 @@ if ($still) { sub use_ifup_command { local ($iface) = @_; -return $gconfig{'os_type'} eq 'debian-linux' && - $gconfig{'os_version'} >= 5 && +return ($gconfig{'os_type'} eq 'debian-linux' && + $gconfig{'os_version'} >= 5 || + $gconfig{'os_type'} eq 'redhat-linux' && + $gconfig{'os_version'} >= 14) && $iface->{'name'} !~ /^(eth|lo)/ && $iface->{'virtual'} eq ''; } diff --git a/net/redhat-linux-lib.pl b/net/redhat-linux-lib.pl index c6f065ee0..df46989db 100755 --- a/net/redhat-linux-lib.pl +++ b/net/redhat-linux-lib.pl @@ -104,6 +104,23 @@ while($f = readdir(CONF)) { $b->{'gateway'} = $conf{'GATEWAY'}; $b->{'gateway6'} = $conf{'IPV6_DEFAULTGW'}; $b->{'mtu'} = $conf{'MTU'}; + $b->{'partner'} = &get_teaming_partner($conf{'DEVICE'}); + my @values = split(/\s+/, $conf{'BONDING_OPTS'}); + foreach my $val (@values) { + my ($k, $v) = split(/=/, $val, 2); + if ($k eq "mode") { + $b->{'mode'} = $v; + } + elsif ($k eq "miimon") { + $b->{'miimon'} = $v; + } + elsif ($k eq "updelay") { + $b->{'updelay'} = $v; + } + elsif ($k eq "downdelay") { + $b->{'downdelay'} = $v; + } + } $b->{'ether'} = $conf{'MACADDR'}; $b->{'dhcp'} = ($conf{'BOOTPROTO'} eq 'dhcp'); $b->{'bootp'} = ($conf{'BOOTPROTO'} eq 'bootp'); @@ -140,6 +157,22 @@ foreach my $b (@rv) { return @rv; } +# save_bond_interface(device, master) +# Create or update a boot-time bond slave interface +sub save_bond_interface +{ +local(%conf); +&lock_file("$net_scripts_dir/ifcfg-$_[0]"); +$conf{'DEVICE'} = $_[0]; +$conf{'BOOTPROTO'} = none; +$conf{'ONBOOT'} = yes; +$conf{'MASTER'} = $_[1]; +$conf{'SLAVE'} = "yes"; +$conf{'USERCTL'} = "no"; +&write_env_file("$net_scripts_dir/ifcfg-$_[0]", \%conf); +&unlock_file("$net_scripts_dir/ifcfg-$_[0]"); +} + # save_interface(&details) # Create or update a boot-time interface sub save_interface @@ -212,6 +245,23 @@ else { "command is installed"); $conf{'TYPE'} = 'Bridge'; } + if ($_[0]->{'fullname'} =~ /^bond(\d+)$/) { + $conf{'BONDING_OPTS'} = "mode=$_[0]->{'mode'}"; + if ($_[0]->{'miimon'}) { + $conf{'BONDING_OPTS'} .= " miimon=$_[0]->{'miimon'}"; + } + if ($_[0]->{'updelay'}) { + $conf{'BONDING_OPTS'} .= " updelay=$_[0]->{'updelay'}"; + } + if ($_[0]->{'downdelay'}) { + $conf{'BONDING_OPTS'} .= " downdelay=$_[0]->{'downdelay'}"; + } + + my @values = split(/\s+/, $_[0]->{'partner'}); + foreach my $val (@values) { + &save_bond_interface($val, $_[0]->{'fullname'}); + } + } } $conf{'NAME'} = $_[0]->{'desc'}; &write_env_file("$net_scripts_dir/ifcfg-$name", \%conf); @@ -807,6 +857,13 @@ return ($gconfig{'os_type'} eq 'redhat-linux' && $gconfig{'os_version'} >= 3.0); } +sub supports_bonding +{ +return $gconfig{'os_type'} eq 'redhat-linux' && + $gconfig{'os_version'} >= 13.0 && + &has_command("ifenslave"); +} + # range_input([&interface]) # Print HTML for a IP range interface sub range_input @@ -897,6 +954,24 @@ sub save_dhcp_hostname { } +# get_teaming_partner(devicename) +# Gets the teamingpartners of a configured bond interface +sub get_teaming_partner +{ +local ($g, $return); +opendir(CONF2, &translate_filename($net_scripts_dir)); +while($g = readdir(CONF2)) { + local %conf2; + if ($g !~ /\.(bak|old)$/i && $g =~ /^ifcfg-([a-z0-9:\.]+)$/) { + &read_env_file("$net_scripts_dir/$g", \%conf2); + if ($conf2{'MASTER'} eq "$_[0]") { + $return .= $conf2{'DEVICE'}." "; + } + } + } +return $return; +} + sub boot_iface_hardware { return $_[0] =~ /^eth/; diff --git a/net/save_bifc.cgi b/net/save_bifc.cgi index 74976fe94..57488803a 100755 --- a/net/save_bifc.cgi +++ b/net/save_bifc.cgi @@ -86,6 +86,12 @@ else { $b->{'name'} = $b->{'fullname'} = "br".$in{'name'}; $b->{'bridge'} = 1; } + elsif ($in{'bond'}) { + # Creating a bond interface + $in{'name'} =~ /^\d+$/ || &error($text{'bifc_ebond'}); + $b->{'name'} = $b->{'fullname'} = "bond".$in{'name'}; + $b->{'bond'} = 1; + } elsif ($in{'name'} =~/^[a-z]+\d*(\.\d+)?$/) { # creating a real interface $b->{'name'} = $in{'name'};