Currently the check for used ports for bonds and bridges happens while rendering '/etc/network/interfaces.new' in PVE::Inotify (pve-common). However at that stage the new/updated interface is already merged with the old settings, making it impossible to indicate where a NIC is currently used.
The code is adapted from the renderer in PVE::Inotify::__write_etc_network_interfaces. Tested on a virtual PVE instance. Signed-off-by: Stoiko Ivanov <s.iva...@proxmox.com> --- PVE/API2/Network.pm | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/PVE/API2/Network.pm b/PVE/API2/Network.pm index 9ac289c4..2d8c4ca1 100644 --- a/PVE/API2/Network.pm +++ b/PVE/API2/Network.pm @@ -301,6 +301,39 @@ my $check_duplicate_gateway6 = sub { return &$check_duplicate($config, $newiface, 'gateway6', 'Default ipv6 gateway'); }; +my $check_duplicate_ports = sub { + my ($config, $newiface, $newparam) = @_; + + my $param_name; + my $get_portlist = sub { + my ($param) = @_; + my $ports = ''; + for my $k (qw(bridge_ports ovs_ports slaves ovs_bonds)) { + if ($param->{$k}) { + $ports .= " $param->{$k}"; + $param_name //= $k; + } + } + return PVE::Tools::split_list($ports); + }; + + my $new_ports = {}; + for my $p ($get_portlist->($newparam)) { + $new_ports->{$p} = 1; + } + return if !(keys %$new_ports); + + for my $iface (keys %$config) { + next if $iface eq $newiface; + + my $d = $config->{$iface}; + for my $p ($get_portlist->($d)) { + raise_param_exc({ $param_name => "$p is already used on interface '$iface'." }) + if $new_ports->{$p}; + } + } +}; + sub ipv6_tobin { return Net::IP::ip_iptobin(Net::IP::ip_expand_address(shift, 6), 6); } @@ -387,6 +420,8 @@ __PACKAGE__->register_method({ &$check_duplicate_gateway6($ifaces, $iface) if $param->{gateway6}; + $check_duplicate_ports->($ifaces, $iface, $param); + $map_cidr_to_address_netmask->($param); &$check_ipv6_settings($param->{address6}, int($param->{netmask6})) @@ -488,6 +523,8 @@ __PACKAGE__->register_method({ &$check_duplicate_gateway6($ifaces, $iface) if $param->{gateway6}; + $check_duplicate_ports->($ifaces, $iface, $param); + if ($param->{address}) { push @$families, 'inet' if !grep(/^inet$/, @$families); } else { -- 2.20.1 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel