all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Christoph Heiss <c.heiss@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH installer v5 08/23] install: network: set up vlan on management interface if requested
Date: Fri,  6 Nov 2026 14:10:37 +0100	[thread overview]
Message-ID: <20261106131058.804870-9-c.heiss@proxmox.com> (raw)
In-Reply-To: <20261106131058.804870-1-c.heiss@proxmox.com>

Adds the necessary configuration to /etc/network/interfaces when a VLAN
ID was configured by the user in the installation config.

Depending on the rest of the network configuration (bridged, bonded), a
separated (dotted) VLAN interface will be created and integrated in the
rest of the configuration as needed.

This follows our recommended approach for setting up such a
network configuration.

Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
---
Had a discussion with @Stefan about this, and this way of configuring
this was the best / most user-friendly we plotted out.

Changes v4 -> v5:
  * no changes

Changes v3 -> v4:
  * no changes

Changes v2 -> v3:
  * new patch

 Proxmox/Install.pm                |  45 +++++++--
 test/generate-ifupdown2-config.pl | 159 ++++++++++++++++++++++++++----
 2 files changed, 175 insertions(+), 29 deletions(-)

diff --git a/Proxmox/Install.pm b/Proxmox/Install.pm
index 9e167d8..b39df6f 100644
--- a/Proxmox/Install.pm
+++ b/Proxmox/Install.pm
@@ -889,14 +889,40 @@ sub generate_ifupdown2_config {
             && ($_->{protocol} // '') eq 'ra';
     } $gateways6->@*;
 
-    if ($iso_env->{cfg}->{bridged_network}) {
-        if ($bond_enabled) {
-            $ifaces .= "auto $ethdev\n" #
-                . "iface $ethdev $ntype manual\n" #
-                . $bond_config;
-        } else {
-            $ifaces .= "iface $ethdev $ntype manual\n";
-        }
+    my $vlan_enabled = Proxmox::Install::Config::get_mngmt_vlan_enabled();
+    my $vlan_id = Proxmox::Install::Config::get_mngmt_vlan_opt('vid');
+
+    # the live environment is not on the management VLAN, so its routes say nothing about it
+    $is_gateway6_from_ra = 0 if $vlan_enabled;
+
+    my $link_config =
+        $bond_enabled
+        ? "auto $ethdev\niface $ethdev $ntype manual\n$bond_config"
+        : "iface $ethdev $ntype manual\n";
+
+    my $get_vlan_config = sub {
+        my ($raw_device) = @_;
+
+        return
+            "\nauto $raw_device.$vlan_id\niface $raw_device.$vlan_id $ntype static\n"
+            . "\taddress $cidr\n"
+            . "\tgateway $gateway\n";
+    };
+
+    if ($iso_env->{cfg}->{bridged_network} && $vlan_enabled) {
+        $ifaces .= $link_config;
+
+        $ifaces .=
+            "\nauto vmbr0\niface vmbr0 $ntype manual\n"
+            . "\tbridge-ports $ethdev\n"
+            . "\tbridge-stp off\n"
+            . "\tbridge-fd 0\n"
+            . "\tbridge-vlan-aware yes\n"
+            . "\tbridge-vids 2-4094\n";
+
+        $ifaces .= $get_vlan_config->('vmbr0');
+    } elsif ($iso_env->{cfg}->{bridged_network}) {
+        $ifaces .= $link_config;
 
         $ifaces .= "\nauto vmbr0\niface vmbr0 $ntype static\n";
 
@@ -908,6 +934,9 @@ sub generate_ifupdown2_config {
         $ifaces .= "\tbridge-ports $ethdev\n" #
             . "\tbridge-stp off\n" #
             . "\tbridge-fd 0\n";
+    } elsif ($vlan_enabled) {
+        $ifaces .= $bond_enabled ? $link_config : "auto $ethdev\n$link_config";
+        $ifaces .= $get_vlan_config->($ethdev);
     } else {
         # if bonding is enabled, this becomes the bond interface stanza
         # otherwise, it's the physical interface stanza
diff --git a/test/generate-ifupdown2-config.pl b/test/generate-ifupdown2-config.pl
index f40689c..9ac9b3d 100755
--- a/test/generate-ifupdown2-config.pl
+++ b/test/generate-ifupdown2-config.pl
@@ -34,6 +34,10 @@ my sub set_config {
 
     Proxmox::Install::Config::merge({
         mngmt_nic => $cfg{bond} ? 'bond0' : 'eno1',
+        mngmt_vlan => {
+            enabled => $cfg{vlan},
+            vid => $cfg{vlan} ? 5 : 0,
+        },
         mngmt_bond => {
             members => $cfg{bond} ? ['12:34:56:ab:cd:ef', 'ab:cd:ef:12:34:56'] : [],
             mode => 'active-backup',
@@ -54,7 +58,7 @@ $expected
 
 source /etc/network/interfaces.d/*
 EOT
-        "$msg (bridge:$current_cfg->{bridge} bond:$current_cfg->{bond})",
+        "$msg (bridge:$current_cfg->{bridge} bond:$current_cfg->{bond} vlan:$current_cfg->{vlan})",
     );
 }
 
@@ -84,7 +88,7 @@ $proxmox_install_runenv->redefine(
         };
     },
 );
-set_config(bridge => 0, bond => 0);
+set_config(bridge => 0, bond => 0, vlan => 0);
 Proxmox::Install::Config::merge({
     cidr => '192.168.0.10/24',
     gateway => '192.168.0.1',
@@ -93,18 +97,22 @@ Proxmox::Install::Config::merge({
 ###
 # There's essentially a matrix to test w.r.t the overall networking setup:
 #
-# +-------+--------+------+
-# | test# | bridge | bond |
-# +=======+========+======+
-# |   1   |    0   |  0   |
-# |   2   |    0   |  1   |
-# |   3   |    1   |  0   |
-# |   4   |    1   |  1   |
-# +-------+--------+------+
+# +-------+--------+------+------+
+# | test# | bridge | bond | vlan |
+# +=======+========+======+======+
+# |   1   |    0   |  0   |  0   |
+# |   2   |    0   |  0   |  1   |
+# |   3   |    0   |  1   |  0   |
+# |   4   |    0   |  1   |  1   |
+# |   5   |    1   |  0   |  0   |
+# |   6   |    1   |  0   |  1   |
+# |   7   |    1   |  1   |  0   |
+# |   8   |    1   |  1   |  1   |
+# +-------+--------+------+------+
 ###
 
 # 1.
-set_config(bridge => 0, bond => 0);
+set_config(bridge => 0, bond => 0, vlan => 0);
 is_generated(
     <<EOT
 auto eno1
@@ -118,7 +126,24 @@ EOT
 );
 
 # 2.
-set_config(bridge => 0, bond => 1);
+set_config(bridge => 0, bond => 0, vlan => 1);
+is_generated(
+    <<EOT
+auto eno1
+iface eno1 inet manual
+
+auto eno1.5
+iface eno1.5 inet static
+	address 192.168.0.10/24
+	gateway 192.168.0.1
+
+iface eno2 inet manual
+EOT
+    , 'host network setup',
+);
+
+# 3.
+set_config(bridge => 0, bond => 1, vlan => 0);
 is_generated(
     <<EOT
 auto bond0
@@ -138,8 +163,32 @@ EOT
     , 'host network setup',
 );
 
-# 3.
-set_config(bridge => 1, bond => 0);
+# 4.
+set_config(bridge => 0, bond => 1, vlan => 1);
+is_generated(
+    <<EOT
+auto bond0
+iface bond0 inet manual
+	bond-slaves eno1 eno2
+	bond-miimon 100
+	bond-mode active-backup
+
+auto bond0.5
+iface bond0.5 inet static
+	address 192.168.0.10/24
+	gateway 192.168.0.1
+
+auto eno1
+iface eno1 inet manual
+
+auto eno2
+iface eno2 inet manual
+EOT
+    , 'host network setup',
+);
+
+# 5.
+set_config(bridge => 1, bond => 0, vlan => 0);
 is_generated(
     <<EOT
 iface eno1 inet manual
@@ -157,8 +206,32 @@ EOT
     , 'host network setup',
 );
 
-# 4.
-set_config(bridge => 1, bond => 1);
+# 6.
+set_config(bridge => 1, bond => 0, vlan => 1);
+is_generated(
+    <<EOT
+iface eno1 inet manual
+
+auto vmbr0
+iface vmbr0 inet manual
+	bridge-ports eno1
+	bridge-stp off
+	bridge-fd 0
+	bridge-vlan-aware yes
+	bridge-vids 2-4094
+
+auto vmbr0.5
+iface vmbr0.5 inet static
+	address 192.168.0.10/24
+	gateway 192.168.0.1
+
+iface eno2 inet manual
+EOT
+    , 'host network setup',
+);
+
+# 7.
+set_config(bridge => 1, bond => 1, vlan => 0);
 is_generated(
     <<EOT
 auto bond0
@@ -184,12 +257,44 @@ EOT
     , 'host network setup',
 );
 
+# 8.
+set_config(bridge => 1, bond => 1, vlan => 1);
+is_generated(
+    <<EOT
+auto bond0
+iface bond0 inet manual
+	bond-slaves eno1 eno2
+	bond-miimon 100
+	bond-mode active-backup
+
+auto vmbr0
+iface vmbr0 inet manual
+	bridge-ports bond0
+	bridge-stp off
+	bridge-fd 0
+	bridge-vlan-aware yes
+	bridge-vids 2-4094
+
+auto vmbr0.5
+iface vmbr0.5 inet static
+	address 192.168.0.10/24
+	gateway 192.168.0.1
+
+auto eno1
+iface eno1 inet manual
+
+auto eno2
+iface eno2 inet manual
+EOT
+    , 'host network setup',
+);
+
 # interface name pinning test
 Proxmox::Install::Config::merge({
     mngmt_nic => 'eno1',
     network_interface_pin_map => $pin_map,
 });
-set_config(bridge => 1, bond => 0);
+set_config(bridge => 1, bond => 0, vlan => 0);
 is_generated(
     <<EOT
 iface nic0 inet manual
@@ -239,7 +344,7 @@ $proxmox_install_runenv->redefine(
         };
     },
 );
-set_config(bridge => 1, bond => 0);
+set_config(bridge => 1, bond => 0, vlan => 0);
 
 is_generated(
     <<EOT
@@ -263,7 +368,7 @@ Proxmox::Install::Config::merge({
     cidr => '2001:db8::1/64',
     gateway => 'fe80::1',
 });
-set_config(bridge => 0, bond => 1);
+set_config(bridge => 0, bond => 1, vlan => 0);
 
 is_generated(
     <<EOT
@@ -289,7 +394,7 @@ Proxmox::Install::Config::merge({
     cidr => '192.168.0.10/24',
     gateway => '192.168.0.1',
 });
-set_config(bridge => 0, bond => 0);
+set_config(bridge => 0, bond => 0, vlan => 0);
 $proxmox_install_runenv->redefine(
     get => sub {
         return {
@@ -330,7 +435,7 @@ EOT
     , 'unpinnable names keep their kernel name',
 );
 
-set_config(bridge => 1, bond => 1);
+set_config(bridge => 1, bond => 1, vlan => 0);
 Proxmox::Install::Config::merge({
     mngmt_nic => 'bond0',
     mngmt_bond => {
@@ -421,4 +526,16 @@ is(
     'unknown bond member is an error',
 );
 
+for my $id (0, 1, 4095, 'abc', '1.5') {
+    eval { Proxmox::Install::Config::set_mngmt_vlan_opt('vid', $id) };
+    like($@, qr/^invalid VLAN tag '\Q$id\E'/, "VLAN tag '$id' is rejected");
+}
+
+Proxmox::Install::Config::set_mngmt_vlan_opt('vid', '0005');
+is(
+    Proxmox::Install::Config::get_mngmt_vlan_opt('vid'),
+    5,
+    'VLAN tag with leading zeros is normalized',
+);
+
 done_testing();
-- 
2.56.0





  parent reply	other threads:[~2026-11-06 13:12 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-06 13:10 [PATCH installer v5 00/23] fix #2164: add bond and vlan setup across all installers Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 01/23] install: run make tidy Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 02/23] tree-wide: use `MacAddress` type instead of string for MAC addresses Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 03/23] install: factor out ifupdown2 config generation into own subroutine Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 04/23] install: do not rely on interface name map to be fully populated Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 05/23] install: config: add option for setting up bond on management interface Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 06/23] install: config: add option for setting up vlan " Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 07/23] install: network: set up management bond if requested Christoph Heiss
2026-11-06 13:10 ` Christoph Heiss [this message]
2026-11-06 13:10 ` [PATCH installer v5 09/23] gui: network: factor out name pinning into advanced options dialog Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 10/23] gui: network: add bond setup options to " Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 11/23] gui: network: add vlan setup options to advanced network dialog Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 12/23] auto: pass through management network bond options to low-level installer Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 13/23] auto: pass through management network vlan " Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 14/23] tui: drop long obsolete comment about logo formatting Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 15/23] tui: views: add widget for displaying a group of checkboxes Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 16/23] tui: network: factor out name pinning into advanced options dialog Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 17/23] tui: network: match form label style when enabling/disabling elements Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 18/23] tui: network: add bond setup options to advanced network dialog Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 19/23] tui: network: add vlan " Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 20/23] gui: network: split advanced options dialog into tabs Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 21/23] tui: " Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 22/23] gui: network: list bond member candidates sharing a MAC address once Christoph Heiss
2026-11-06 13:10 ` [PATCH installer v5 23/23] tui: " Christoph Heiss

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261106131058.804870-9-c.heiss@proxmox.com \
    --to=c.heiss@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal