From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id E7BAD20EC7F for ; Tue, 23 Apr 2024 15:03:25 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 4D9073253B; Tue, 23 Apr 2024 15:03:29 +0200 (CEST) From: Wolfgang Bumiller To: pve-devel@lists.proxmox.com Date: Tue, 23 Apr 2024 15:03:17 +0200 Message-Id: <20240423130317.309150-1-w.bumiller@proxmox.com> X-Mailer: git-send-email 2.39.2 MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.086 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [ifupdown2-typeless.pl, inotify.pm] Subject: [pve-devel] [PATCH common] interfaces: support stanzas without types/methods X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" This is allowed in ifupdown2 and previously interfaces named 'vmbr\d+' were recognized as bridges even if they used this mode. With commit e68ebda4f109 this is no longer the case. Fixes: e68ebda4f109 ("fix #545: interfaces: allow arbitrary bridge names in network config") Signed-off-by: Wolfgang Bumiller --- The `__interface_to_string portion` is much better viewied with `-w` src/PVE/INotify.pm | 97 +++++++++++++------ .../t.ifupdown2-typeless.pl | 47 +++++++++ 2 files changed, 117 insertions(+), 27 deletions(-) create mode 100644 test/etc_network_interfaces/t.ifupdown2-typeless.pl diff --git a/src/PVE/INotify.pm b/src/PVE/INotify.pm index 4568593..8a4a810 100644 --- a/src/PVE/INotify.pm +++ b/src/PVE/INotify.pm @@ -912,23 +912,29 @@ sub __read_etc_network_interfaces { # FIXME: handle those differently? auto makes it required on-boot, vs. best-effort $ifaces->{$_}->{autostart} = 1 for split (/\s+/, $2); - } elsif ($line =~ m/^\s*iface\s+(\S+)\s+(inet6?)\s+(\S+)\s*$/) { + } elsif ($line =~ m/^\s*iface\s+(\S+)(?:\s+(inet6?)\s+(\S+))?\s*$/) { my $i = $1; my $family = $2; my $f = { method => $3 }; # by family, merged to $d with a $suffix - (my $suffix = $family) =~ s/^inet//; + my $suffix = $family; + $suffix =~ s/^inet// if defined $suffix; my $d = $ifaces->{$i} ||= {}; $d->{priority} = $priority++ if !$d->{priority}; + + # $family may be undef, an undef family means we have a stanza + # without an `inet` or `inet6` section push @{$d->{families}}, $family; + while (defined ($line = <$fh>)) { $line =~ s/\s+$//; # drop trailing whitespaces if ($line =~ m/^\s*#(.*?)\s*$/) { - $f->{comments} = '' if !$f->{comments}; + my $pushto = defined($suffix) ? $f : $d; + $pushto->{comments} = '' if !$pushto->{comments}; my $comment = decode('UTF-8', $1); - $f->{comments} .= "$comment\n"; + $pushto->{comments} .= "$comment\n"; } elsif ($line =~ m/^\s*(?:(?:iface|mapping|auto|source|source-directory)\s|allow-)/) { last; } elsif ($line =~ m/^\s*((\S+)\s+(.+))$/) { @@ -967,7 +973,17 @@ sub __read_etc_network_interfaces { }; if ($id eq 'address' || $id eq 'netmask' || $id eq 'broadcast' || $id eq 'gateway') { - $f->{$id} = $value; + if (defined($suffix)) { + $d->{$id.$suffix} = $value; + } elsif ($id ne 'netmask') { + if ($value =~ /:/) { + $d->{$id.'6'} = $value; + } else { + $d->{$id} = $value; + } + } else { + $d->{$id} = $value; + } } elsif ($simple_options->{$id}) { $d->{$id} = $value; } elsif ($id eq 'slaves' || $id eq 'bridge_ports') { @@ -1002,13 +1018,16 @@ sub __read_etc_network_interfaces { } elsif ($id eq 'vxlan-remoteip') { push @{$d->{$id}}, $value; } else { - push @{$f->{options}}, $option; + my $pushto = defined($suffix) ? $f : $d; + push @{$pushto->{options}}, $option; } } else { last; } } - $d->{"$_$suffix"} = $f->{$_} for keys $f->%*; + if (defined($suffix)) { + $d->{"$_$suffix"} = $f->{$_} for keys $f->%*; + } last SECTION if !defined($line); redo SECTION; } elsif ($line =~ /\w/) { @@ -1227,24 +1246,37 @@ sub _get_cidr { sub __interface_to_string { my ($iface, $d, $family, $first_block, $ifupdown2) = @_; - (my $suffix = $family) =~ s/^inet//; + my $suffix = $family; + $suffix =~ s/^inet// if defined($suffix); - return '' if !($d && $d->{"method$suffix"}); + return '' if $family && !($d && $d->{"method$suffix"}); - my $raw = "iface $iface $family " . $d->{"method$suffix"} . "\n"; + my $raw = "iface $iface"; + $raw .= " $family " . $d->{"method$suffix"} if defined $family; + $raw .= "\n"; - if (my $addr = $d->{"address$suffix"}) { - if ($addr !~ /\/\d+$/ && $d->{"netmask$suffix"}) { - if ($d->{"netmask$suffix"} =~ m/^\d+$/) { - $addr .= "/" . $d->{"netmask$suffix"}; - } elsif (my $mask = PVE::JSONSchema::get_netmask_bits($d->{"netmask$suffix"})) { - $addr .= "/" . $mask; + my $add_addr = sub { + my ($suffix) = @_; + if (my $addr = $d->{"address$suffix"}) { + if ($addr !~ /\/\d+$/ && $d->{"netmask$suffix"}) { + if ($d->{"netmask$suffix"} =~ m/^\d+$/) { + $addr .= "/" . $d->{"netmask$suffix"}; + } elsif (my $mask = PVE::JSONSchema::get_netmask_bits($d->{"netmask$suffix"})) { + $addr .= "/" . $mask; + } } + $raw .= "\taddress ${addr}\n"; } - $raw .= "\taddress ${addr}\n"; - } - $raw .= "\tgateway " . $d->{"gateway$suffix"} . "\n" if $d->{"gateway$suffix"}; + $raw .= "\tgateway " . $d->{"gateway$suffix"} . "\n" if $d->{"gateway$suffix"}; + }; + + if ($family) { + $add_addr->($suffix); + } else { + $add_addr->(''); + $add_addr->('6'); + } my $done = { type => 1, priority => 1, method => 1, active => 1, exists => 1, comments => 1, @@ -1413,14 +1445,25 @@ sub __interface_to_string { } } - foreach my $option (@{$d->{"options$suffix"}}) { - $raw .= "\t$option\n"; - } + my $add_options_comments = sub { + my ($suffix) = @_; + + foreach my $option (@{$d->{"options$suffix"}}) { + $raw .= "\t$option\n"; + } - # add comments - my $comments = $d->{"comments$suffix"} || ''; - foreach my $cl (split(/\n/, $comments)) { - $raw .= "#$cl\n"; + # add comments + my $comments = $d->{"comments$suffix"} || ''; + foreach my $cl (split(/\n/, $comments)) { + $raw .= "#$cl\n"; + } + }; + + if ($family) { + $add_options_comments->($suffix); + } else { + $add_options_comments->(''); + $add_options_comments->('6'); } $raw .= "\n"; @@ -1750,7 +1793,7 @@ NETWORKDOC } # if 'inet6' is the only family - if (scalar($d->{families}->@*) == 1 && $d->{families}[0] eq 'inet6') { + if (scalar($d->{families}->@*) == 1 && defined($d->{families}->[0]) && $d->{families}->[0] eq 'inet6') { $d->{comments6} = delete $d->{comments}; } diff --git a/test/etc_network_interfaces/t.ifupdown2-typeless.pl b/test/etc_network_interfaces/t.ifupdown2-typeless.pl new file mode 100644 index 0000000..d0ec5e6 --- /dev/null +++ b/test/etc_network_interfaces/t.ifupdown2-typeless.pl @@ -0,0 +1,47 @@ +my $ip = '10.0.0.2/24'; +my $gw = '10.0.0.1'; +my $ip6 = 'fc05::1:2/112'; +my $gw6 = 'fc05::1:1'; + +r(load('base') . <<"EOF"); +auto vmbr1 +iface vmbr1 + address 1.2.3.4/24 + address fccc::a:1/64 + gateway 1.2.3.1 + gateway fccc::1 + bridge-ports eth0 + bridge-stp off + bridge-fd 0 +# Comment + +EOF + +my $run = 'first'; +my $ifaces = $config->{ifaces}; + +my $ck = sub { + my ($i, $v, $e) = @_; + $ifaces->{$i}->{$v} eq $e + or die "$run run: $i variable $v: got \"$ifaces->{$i}->{$v}\", expected: $e\n"; +}; + +my $check_config = sub { + $ck->('vmbr1', type => 'bridge'); + $ck->('vmbr1', cidr => '1.2.3.4/24'); + $ck->('vmbr1', gateway => '1.2.3.1'); + $ck->('vmbr1', cidr6 => 'fccc::a:1/64'); + $ck->('vmbr1', gateway6 => 'fccc::1'); +}; + +$check_config->(); + +# idempotency +save('idem', w()); +r(load('idem')); +expect load('idem'); + +$run = 'second'; +$check_config->(); + +1; -- 2.39.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel