Signed-off-by: Alexandre Derumier <aderum...@odiso.com> --- src/PVE/INotify.pm | 64 +++++++++++++------ test/etc_network_interfaces/t.bridge-v4-v6.pl | 4 +- .../t.create_network.pl | 6 +- .../t.list-interfaces.pl | 47 +++++++++----- .../t.ovs_bridge_allow.pl | 2 +- .../etc_network_interfaces/t.unknown_order.pl | 2 +- .../t.update_network.pl | 8 +-- 7 files changed, 88 insertions(+), 45 deletions(-)
diff --git a/src/PVE/INotify.pm b/src/PVE/INotify.pm index e9dc485..2bb5272 100644 --- a/src/PVE/INotify.pm +++ b/src/PVE/INotify.pm @@ -966,7 +966,9 @@ sub __read_etc_network_interfaces { 'vxlan-physdev' => 1, 'vxlan-local-tunnelip' => 1 }; - if (($id eq 'address') || ($id eq 'netmask') || ($id eq 'broadcast') || ($id eq 'gateway')) { + if ($id eq 'address') { + push @{$f->{$id}}, $value; + } elsif (($id eq 'netmask') || ($id eq 'broadcast') || ($id eq 'gateway')) { $f->{$id} = $value; } elsif ($simple_options->{$id}) { $d->{$id} = $value; @@ -1104,23 +1106,29 @@ sub __read_etc_network_interfaces { } } - # map address and netmask to cidr - if ($d->{address}) { - if ($d->{netmask} && $d->{netmask} =~ m/^\d+$/) { # e.g. netmask 20 - $d->{address} = $d->{address} . "/" . $d->{netmask}; - } elsif ($d->{netmask} && - (my $cidr = PVE::JSONSchema::get_netmask_bits($d->{netmask}))) { # e.g. netmask 255.255.255.0 - $d->{address} = $d->{address} . "/" . $cidr; + my $addresses = $d->{address}; + foreach my $address (@{$addresses}) { + # map address and netmask to cidr + if ($address) { + if ($d->{netmask} && $d->{netmask} =~ m/^\d+$/) { # e.g. netmask 20 + $address = $address . "/" . $d->{netmask}; + } elsif ($d->{netmask} && + (my $cidr = PVE::JSONSchema::get_netmask_bits($d->{netmask}))) { # e.g. netmask 255.255.255.0 + $address = $address . "/" . $cidr; + } + #for api compatibility, first address only + $d->{cidr} = $address if !$d->{cidr}; } - #for api compatibility - $d->{cidr} = $d->{address} - } + } - # map address6 and netmask6 to cidr6 - if ($d->{address6}) { - $d->{address6} .= "/" . $d->{netmask6} if $d->{address6} !~ m!^(.*)/(\d+)$! && $d->{netmask6}; - #for api compatibility - $d->{cidr6} = $d->{address6} + my $addresses6 = $d->{address6}; + foreach my $address6 (@{$addresses6}) { + # map address6 and netmask6 to cidr6 + if ($address6) { + $address6 .= "/" . $d->{netmask6} if $address6 !~ m!^(.*)/(\d+)$! && $d->{netmask6}; + #for api compatibility, first address only + $d->{cidr6} = $address6 if !$d->{cidr6}; + } } $d->{method} = 'manual' if !$d->{method}; @@ -1168,7 +1176,12 @@ sub __interface_to_string { my $raw = ''; $raw .= "iface $iface $family " . $d->{"method$suffix"} . "\n"; - $raw .= "\taddress " . $d->{"address$suffix"} . "\n" if $d->{"address$suffix"}; + + my $addresses = $d->{"address$suffix"}; + foreach my $address (@{$addresses}) { + $raw .= "\taddress " . $address . "\n"; + } + $raw .= "\tgateway " . $d->{"gateway$suffix"} . "\n" if $d->{"gateway$suffix"}; my $done = { type => 1, priority => 1, method => 1, active => 1, exists => 1, @@ -1557,9 +1570,20 @@ sub __write_etc_network_interfaces { } my $n = $ifaces_copy->{$p}; die "bridge '$iface' - unable to find bridge port '$p'\n" if !$n; - die "iface $p - ip address can't be set on interface if bridged in $iface\n" - if ($n->{method} && $n->{method} eq 'static' && $n->{address} ne '0.0.0.0') || - ($n->{method6} && $n->{method6} eq 'static' && $n->{address} ne '::'); + if ($n->{method} && $n->{method} eq 'static') { + my $addresses = $d->{address}; + foreach my $address (@{$addresses}) { + die "iface $p - ip address can't be set on interface if bridged in $iface\n" if $address ne '0.0.0.0'; + } + } + + if ($n->{method6} && $n->{method6} eq 'static') { + my $addresses = $d->{address6}; + foreach my $address (@{$addresses}) { + die "iface $p - ip address can't be set on interface if bridged in $iface\n" if $address ne '::'; + } + } + &$check_mtu($ifaces_copy, $p, $iface); $bridgeports->{$p} = $iface; } diff --git a/test/etc_network_interfaces/t.bridge-v4-v6.pl b/test/etc_network_interfaces/t.bridge-v4-v6.pl index 07c1c03..8693df8 100644 --- a/test/etc_network_interfaces/t.bridge-v4-v6.pl +++ b/test/etc_network_interfaces/t.bridge-v4-v6.pl @@ -19,7 +19,7 @@ EOF # add an ip and disable previously enabled autostart update_iface('vmbr0', [ { family => 'inet', - address => $ip, + address => [$ip], gateway => $gw } ], autostart => 0); @@ -36,7 +36,7 @@ save('with-ipv4', w()); update_iface('vmbr0', [ { family => 'inet6', - address => $ip6, + address => [$ip6], gateway => $gw6 } ]); expect load('with-ipv4') . <<"EOF"; diff --git a/test/etc_network_interfaces/t.create_network.pl b/test/etc_network_interfaces/t.create_network.pl index 9bb26bd..e3a17df 100644 --- a/test/etc_network_interfaces/t.create_network.pl +++ b/test/etc_network_interfaces/t.create_network.pl @@ -14,6 +14,7 @@ r(load('brbase')); # my $ip = '192.168.0.2/24'; +my $ip2 = '192.168.1.2/24'; my $gw = '192.168.0.1'; my $svcnodeip = '239.192.105.237'; my $physdev = 'eth0'; @@ -43,7 +44,7 @@ chomp $vmbr0_part; $config->{ifaces}->{eth1} = { type => 'eth', method => 'static', - address => $ip, + address => [$ip, $ip2], gateway => $gw, families => ['inet'], autostart => 1 @@ -53,6 +54,7 @@ my $eth1_part = <<"PART"; auto eth1 iface eth1 inet static address $ip + address $ip2 gateway $gw PART chomp $eth1_part; @@ -489,7 +491,7 @@ my $gw = 'fc05::1'; $config->{ifaces}->{eth1} = { type => 'eth', method6 => 'static', - address6 => $ip, + address6 => [$ip], netmask6 => $nm, gateway6 => $gw, families => ['inet6'], diff --git a/test/etc_network_interfaces/t.list-interfaces.pl b/test/etc_network_interfaces/t.list-interfaces.pl index 5925c35..d4f5065 100644 --- a/test/etc_network_interfaces/t.list-interfaces.pl +++ b/test/etc_network_interfaces/t.list-interfaces.pl @@ -16,10 +16,10 @@ eth100: /proc/net/dev my %wanted = ( - vmbr0 => { address => '192.168.1.2/24', + vmbr0 => { address => ['192.168.1.2/24'], gateway => '192.168.1.1', - address6 => 'fc05::1:1/112'}, - vmbr1 => { address => '10.0.0.5/24'} + address6 => ['fc05::1:1/112']}, + vmbr1 => { address => ['10.0.0.5/24', '10.0.0.6/24']} ); save('interfaces', <<"/etc/network/interfaces"); @@ -37,23 +37,24 @@ iface eth100 inet manual auto vmbr0 iface vmbr0 inet static - address 192.168.1.2 - netmask 24 - gateway $wanted{vmbr0}->{gateway} + address 192.168.1.2 + netmask 24 + gateway $wanted{vmbr0}->{gateway} bridge_ports eth0 bridge_stp off bridge_fd 0 iface vmbr0 inet6 static - address fc05::1:1 - netmask 112 + address fc05::1:1 + netmask 112 source-directory before-ovs.d allow-ovs vmbr1 iface vmbr1 inet static - address 10.0.0.5 - netmask 255.255.255.0 + address 10.0.0.5 + address 10.0.0.6 + netmask 255.255.255.0 ovs_type OVSBridge ovs_ports eth100 @@ -73,11 +74,27 @@ defined($ifaces->{"eth$_"}) # check configuration foreach my $ifname (keys %wanted) { my $if = $wanted{$ifname}; - $ifaces->{$ifname}->{$_} eq $if->{$_} - or die "unexpected $_ for interface $ifname: \"" - . $ifaces->{$ifname}->{$_} - . "\", expected: \"$if->{$_}\"\n" - foreach (keys %$if); + use Data::Dumper; + + foreach my $key (keys %{$if}) { + + if(ref($if->{$key}) eq 'ARRAY') { + my $res1 = $if->{$key}; + my $res2 = $ifaces->{$ifname}->{$key}; + foreach my $index (0..$#{$res1}){ + if ($res1->[$index] != $res2->[$index]) { + die " unexpected keys $res2->[$index] for interface $ifname:". $res2->[$index]." expected: $res1->[$index]"; + } + } + } else { + + $ifaces->{$ifname}->{$key} eq $if->{$key} + or die "unexpected $key for interface $ifname: \"" + . $ifaces->{$ifname}->{$key} + . "\", expected: \"$if->{$key}\"\n" + } + } + } my $ck = sub { diff --git a/test/etc_network_interfaces/t.ovs_bridge_allow.pl b/test/etc_network_interfaces/t.ovs_bridge_allow.pl index 9479ff5..d5d2505 100644 --- a/test/etc_network_interfaces/t.ovs_bridge_allow.pl +++ b/test/etc_network_interfaces/t.ovs_bridge_allow.pl @@ -15,7 +15,7 @@ r(''); new_iface('vmbr0', 'OVSBridge', [ { family => 'inet', - address => $ip, + address => [$ip], gateway => $gw } ], autostart => 1); diff --git a/test/etc_network_interfaces/t.unknown_order.pl b/test/etc_network_interfaces/t.unknown_order.pl index cd8f51b..082cf48 100644 --- a/test/etc_network_interfaces/t.unknown_order.pl +++ b/test/etc_network_interfaces/t.unknown_order.pl @@ -85,7 +85,7 @@ IFACES } r(wanted(13)); -update_iface('bond1', [ { family => 'inet', address => '10.10.10.11/24' } ]); +update_iface('bond1', [ { family => 'inet', address => ['10.10.10.11/24'] } ]); expect wanted(11); 1; diff --git a/test/etc_network_interfaces/t.update_network.pl b/test/etc_network_interfaces/t.update_network.pl index 18bba00..a7cbf37 100644 --- a/test/etc_network_interfaces/t.update_network.pl +++ b/test/etc_network_interfaces/t.update_network.pl @@ -15,7 +15,7 @@ r(load('brbase')); $config->{ifaces}->{eth1} = { type => 'eth', method => 'static', - address => $ip, + address => [$ip], gateway => $gw, families => ['inet'], autostart => 1 @@ -49,7 +49,7 @@ expect load('ipv4'); $config->{ifaces}->{eth1}->{$_->[0]} = $_->[1] foreach ( [ method6 => 'static' ], - [ address6 => $ip6 ], + [ address6 => [$ip6] ], [ netmask6 => $nm6 ], [ gateway6 => $gw6 ], [ families => ['inet', 'inet6'] ] @@ -91,11 +91,11 @@ r(load('ipv4')); $config->{ifaces}->{eth1} = { type => 'eth', method => 'static', - address => $ip, + address => [$ip], netmask => $nm, gateway => $gw, method6 => 'static', - address6 => $ip6, + address6 => [$ip6], netmask6 => $nm6, gateway6 => $gw6, families => ['inet', 'inet6'], -- 2.20.1 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel