mirror of
https://github.com/webmin/webmin.git
synced 2026-08-22 15:00:34 +01:00
Merge pull request #2795 from macmon/fix/net-virtual-iface-deletion
MM-12032 Fix bond/VLAN/bridge not removed from active list on delete
This commit is contained in:
@@ -230,12 +230,12 @@ if ($cfg->{'bridge'}) {
|
||||
|
||||
# Set bonding parameters
|
||||
if(($cfg->{'bond'} == 1) && ($gconfig{'os_version'} >= 5)) {
|
||||
push(@options, [&bonding_option('mode').' '.$cfg->{'mode'}]);
|
||||
push(@options, [&bonding_option('miimon').' '.$cfg->{'miimon'}]) if ($cfg->{'miimon'});
|
||||
push(@options, [&bonding_option('updelay').' '.$cfg->{'updelay'}]) if ($cfg->{'updelay'});
|
||||
push(@options, [&bonding_option('downdelay').' '.$cfg->{'downdelay'}]) if ($cfg->{'downdelay'});
|
||||
push(@options, [&bonding_option('primary').' '.$cfg->{'primary'}]) if ($cfg->{'primary'});
|
||||
push(@options, ['slaves '.$cfg->{'partner'}]);
|
||||
push(@options, [&bonding_option('mode'), $cfg->{'mode'}]);
|
||||
push(@options, [&bonding_option('miimon'), $cfg->{'miimon'}]) if ($cfg->{'miimon'});
|
||||
push(@options, [&bonding_option('updelay'), $cfg->{'updelay'}]) if ($cfg->{'updelay'});
|
||||
push(@options, [&bonding_option('downdelay'), $cfg->{'downdelay'}]) if ($cfg->{'downdelay'});
|
||||
push(@options, [&bonding_option('primary'), $cfg->{'primary'}]) if ($cfg->{'primary'});
|
||||
push(@options, ['slaves', $cfg->{'partner'}]);
|
||||
}
|
||||
elsif ($cfg->{'bond'} == 1) {
|
||||
push(@options, ['up', '/sbin/ifenslave '.$cfg->{'name'}." ".
|
||||
|
||||
@@ -51,6 +51,10 @@ foreach $d (reverse(@d)) {
|
||||
else {&unload_module($b->{'name'});}
|
||||
}
|
||||
}
|
||||
# Remove the virtual device after deactivation
|
||||
if (defined(&destroy_interface_device)) {
|
||||
&destroy_interface_device($b);
|
||||
}
|
||||
}
|
||||
|
||||
# Delete config
|
||||
|
||||
@@ -329,9 +329,22 @@ if (&has_command("ip") && $a->{'bond'} && $a->{'up'} && !$old) {
|
||||
}
|
||||
}
|
||||
|
||||
if (($a->{'bond'} || $a->{'vlan'} || !&has_command("ifconfig")) &&
|
||||
&has_command("ip")) {
|
||||
# For a real interface, activate or de-activate the link
|
||||
if (&has_command("ip") && $a->{'bridge'} && $a->{'up'} && !$old) {
|
||||
# Create the bridge before assigning addresses to it.
|
||||
my $cmd = "ip link add ".quotemeta($a->{'name'})." type bridge";
|
||||
my $out = &backquote_logged("$cmd 2>&1");
|
||||
&error("Failed to create bridge device : $out") if ($?);
|
||||
if ($a->{'bridgeto'}) {
|
||||
$cmd = "ip link set dev ".quotemeta($a->{'bridgeto'}).
|
||||
" master ".quotemeta($a->{'name'});
|
||||
$out = &backquote_logged("$cmd 2>&1");
|
||||
&error("Failed to add interface to bridge : $out") if ($?);
|
||||
}
|
||||
}
|
||||
|
||||
if (&has_command("ip")) {
|
||||
# Manage link state for all interfaces when ip is used, since ip is also
|
||||
# used for address assignment below regardless of ifconfig availability.
|
||||
if ($a->{'virtual'} eq '' && $a->{'up'} && (!$old || !$old->{'up'})) {
|
||||
# Bring up
|
||||
my $cmd = "ip link set dev ".quotemeta($devname)." up";
|
||||
@@ -597,6 +610,20 @@ else {
|
||||
}
|
||||
}
|
||||
|
||||
# destroy_interface_device(&details)
|
||||
# Remove a virtual network device (bond, VLAN, bridge) from the kernel.
|
||||
# Should be called after deactivate_interface when deleting, not just
|
||||
# deactivating, a virtual interface.
|
||||
sub destroy_interface_device
|
||||
{
|
||||
my ($a) = @_;
|
||||
if (&has_command("ip") && $a->{'virtual'} eq '' &&
|
||||
(&use_ifup_command($a) || $a->{'bridge'})) {
|
||||
&backquote_logged("ip link delete ".
|
||||
quotemeta($a->{'fullname'} || $a->{'name'})." 2>&1");
|
||||
}
|
||||
}
|
||||
|
||||
# use_ifup_command(&iface)
|
||||
# Returns 1 if the ifup command must be used to bring up some interface.
|
||||
# True on Debian 5.0+ for non-ethernet, typically bonding and VLAN tagged interfaces.
|
||||
|
||||
@@ -32,6 +32,10 @@ if ($in{'delete'} || $in{'unapply'}) {
|
||||
else {
|
||||
&deactivate_interface($act);
|
||||
}
|
||||
# Remove the virtual device after deactivation
|
||||
if (defined(&destroy_interface_device)) {
|
||||
&destroy_interface_device($b);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -964,4 +964,89 @@ is_deeply(\@commands,
|
||||
"cd / ; ifconfig eth0.10 10\\.0\\.0\\.2 netmask 255\\.255\\.255\\.0 up 2>&1" ],
|
||||
"Linux VLAN interface falls back to vconfig without ip");
|
||||
|
||||
# Test: Bond deactivation only brings it down, does not delete device
|
||||
@commands = ( );
|
||||
{
|
||||
no warnings 'redefine';
|
||||
local *main::has_command = sub {
|
||||
return $_[0] eq "ip" ? "/sbin/ip" : undef;
|
||||
};
|
||||
main::deactivate_interface({
|
||||
'name' => 'bond0',
|
||||
'fullname' => 'bond0',
|
||||
'virtual' => '',
|
||||
'address' => '10.0.0.2',
|
||||
'netmask' => '255.255.255.0',
|
||||
'address6' => [ ],
|
||||
'netmask6' => [ ],
|
||||
'up' => 1
|
||||
});
|
||||
}
|
||||
is_deeply(\@commands, [
|
||||
"ip addr del 10\\.0\\.0\\.2\\/24 dev bond0 2>&1",
|
||||
"ip link set dev bond0 down 2>&1"
|
||||
], "Linux bond deactivation removes address and brings link down");
|
||||
|
||||
# Test: Bond deletion removes virtual device after deactivation
|
||||
@commands = ( );
|
||||
{
|
||||
no warnings 'redefine';
|
||||
no warnings 'once';
|
||||
local $main::gconfig{'os_type'} = 'debian-linux';
|
||||
local $main::gconfig{'os_version'} = 12;
|
||||
local *main::has_command = sub {
|
||||
return $_[0] eq "ip" ? "/sbin/ip" :
|
||||
$_[0] eq "ifup" ? "/sbin/ifup" : undef;
|
||||
};
|
||||
main::deactivate_interface({
|
||||
'name' => 'bond0',
|
||||
'fullname' => 'bond0',
|
||||
'virtual' => '',
|
||||
'address' => '10.0.0.2',
|
||||
'netmask' => '255.255.255.0',
|
||||
'address6' => [ ],
|
||||
'netmask6' => [ ],
|
||||
'up' => 1
|
||||
});
|
||||
# Simulate delete path: destroy_interface_device after deactivation
|
||||
my $b = { 'name' => 'bond0', 'fullname' => 'bond0', 'virtual' => '' };
|
||||
main::destroy_interface_device($b);
|
||||
}
|
||||
is_deeply(\@commands, [
|
||||
"ip addr del 10\\.0\\.0\\.2\\/24 dev bond0 2>&1",
|
||||
"ip link set dev bond0 down 2>&1",
|
||||
"ip link delete bond0 2>&1"
|
||||
], "Linux bond deletion removes device after deactivation");
|
||||
|
||||
# Test: VLAN deletion removes virtual device after deactivation
|
||||
@commands = ( );
|
||||
{
|
||||
no warnings 'redefine';
|
||||
no warnings 'once';
|
||||
local $main::gconfig{'os_type'} = 'debian-linux';
|
||||
local $main::gconfig{'os_version'} = 12;
|
||||
local *main::has_command = sub {
|
||||
return $_[0] eq "ip" ? "/sbin/ip" :
|
||||
$_[0] eq "ifup" ? "/sbin/ifup" : undef;
|
||||
};
|
||||
main::deactivate_interface({
|
||||
'name' => 'eth0.10',
|
||||
'fullname' => 'eth0.10',
|
||||
'virtual' => '',
|
||||
'address' => '10.0.10.2',
|
||||
'netmask' => '255.255.255.0',
|
||||
'address6' => [ ],
|
||||
'netmask6' => [ ],
|
||||
'up' => 1
|
||||
});
|
||||
# Simulate delete path: destroy_interface_device after deactivation
|
||||
my $b = { 'name' => 'eth0.10', 'fullname' => 'eth0.10', 'virtual' => '' };
|
||||
main::destroy_interface_device($b);
|
||||
}
|
||||
is_deeply(\@commands, [
|
||||
"ip addr del 10\\.0\\.10\\.2\\/24 dev eth0\\.10 2>&1",
|
||||
"ip link set dev eth0\\.10 down 2>&1",
|
||||
"ip link delete eth0\\.10 2>&1"
|
||||
], "Linux VLAN deletion removes device after deactivation");
|
||||
|
||||
done_testing();
|
||||
|
||||
Reference in New Issue
Block a user