From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 73BA8C1CFE for ; Thu, 18 Jan 2024 16:45:22 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 5D40E17F1E for ; Thu, 18 Jan 2024 16:45:22 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Thu, 18 Jan 2024 16:45:21 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id A2A0449212 for ; Thu, 18 Jan 2024 16:45:21 +0100 (CET) From: Stefan Lendl To: pbs-devel@lists.proxmox.com Date: Thu, 18 Jan 2024 16:44:18 +0100 Message-ID: <20240118154424.794624-4-s.lendl@proxmox.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20240118154424.794624-1-s.lendl@proxmox.com> References: <20240118154424.794624-1-s.lendl@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.034 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 T_SCC_BODY_TEXT_LINE -0.01 - Subject: [pbs-devel] [PATCH proxmox-backup v2 3/9] config: write vlan network interface X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 18 Jan 2024 15:45:22 -0000 add vlan_id and vlan_raw_device to Interface struct write them out if the interface type is Vlan add several tests Signed-off-by: Stefan Lendl Tested-by: Lukas Wagner Reviewd-by: Lukas Wagner --- pbs-api-types/src/network.rs | 17 ++++++++ pbs-config/src/network/mod.rs | 73 ++++++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/pbs-api-types/src/network.rs b/pbs-api-types/src/network.rs index e3a5e481..fe083dc6 100644 --- a/pbs-api-types/src/network.rs +++ b/pbs-api-types/src/network.rs @@ -224,6 +224,15 @@ pub const NETWORK_INTERFACE_LIST_SCHEMA: Schema = schema: NETWORK_INTERFACE_ARRAY_SCHEMA, optional: true, }, + "vlan-id": { + description: "VLAN ID.", + type: u16, + optional: true, + }, + "vlan-raw-device": { + schema: NETWORK_INTERFACE_NAME_SCHEMA, + optional: true, + }, bond_mode: { type: LinuxBondMode, optional: true, @@ -287,6 +296,12 @@ pub struct Interface { /// Enable bridge vlan support. #[serde(skip_serializing_if = "Option::is_none")] pub bridge_vlan_aware: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "vlan-id")] + pub vlan_id: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "vlan-raw-device")] + pub vlan_raw_device: Option, #[serde(skip_serializing_if = "Option::is_none")] pub slaves: Option>, @@ -319,6 +334,8 @@ impl Interface { mtu: None, bridge_ports: None, bridge_vlan_aware: None, + vlan_id: None, + vlan_raw_device: None, slaves: None, bond_mode: None, bond_primary: None, diff --git a/pbs-config/src/network/mod.rs b/pbs-config/src/network/mod.rs index 7fec7e29..02117535 100644 --- a/pbs-config/src/network/mod.rs +++ b/pbs-config/src/network/mod.rs @@ -79,6 +79,14 @@ fn write_iface_attributes(iface: &Interface, w: &mut dyn Write) -> Result<(), Er writeln!(w, "\tbond-slaves {}", slaves.join(" "))?; } } + NetworkInterfaceType::Vlan => { + if let Some(vlan_id) = iface.vlan_id { + writeln!(w, "\tvlan-id {vlan_id}")?; + } + if let Some(vlan_raw_device) = &iface.vlan_raw_device { + writeln!(w, "\tvlan-raw-device {vlan_raw_device}")?; + } + } _ => {} } @@ -580,5 +588,68 @@ iface enp3s0 inet static .trim() ); } -} + #[test] + fn test_write_network_config_vlan_id_in_name() { + let iface_name = String::from("vmbr0.100"); + let mut iface = Interface::new(iface_name.clone()); + iface.interface_type = Vlan; + iface.method = Some(Manual); + iface.active = true; + + let nw_config = NetworkConfig { + interfaces: BTreeMap::from([(iface_name.clone(), iface)]), + order: vec![Iface(iface_name.clone())], + }; + assert_eq!( + String::try_from(nw_config).unwrap().trim(), + "iface vmbr0.100 inet manual" + ); + } + + #[test] + fn test_write_network_config_vlan_with_raw_device() { + let iface_name = String::from("vlan100"); + let mut iface = Interface::new(iface_name.clone()); + iface.interface_type = Vlan; + iface.vlan_raw_device = Some(String::from("vmbr0")); + iface.method = Some(Manual); + iface.active = true; + + let nw_config = NetworkConfig { + interfaces: BTreeMap::from([(iface_name.clone(), iface)]), + order: vec![Iface(iface_name.clone())], + }; + assert_eq!( + String::try_from(nw_config).unwrap().trim(), + r#" +iface vlan100 inet manual + vlan-raw-device vmbr0"# + .trim() + ); + } + + #[test] + fn test_write_network_config_vlan_with_individual_name() { + let iface_name = String::from("individual_name"); + let mut iface = Interface::new(iface_name.clone()); + iface.interface_type = Vlan; + iface.vlan_raw_device = Some(String::from("vmbr0")); + iface.vlan_id = Some(100); + iface.method = Some(Manual); + iface.active = true; + + let nw_config = NetworkConfig { + interfaces: BTreeMap::from([(iface_name.clone(), iface)]), + order: vec![Iface(iface_name.clone())], + }; + assert_eq!( + String::try_from(nw_config).unwrap().trim(), + r#" +iface individual_name inet manual + vlan-id 100 + vlan-raw-device vmbr0"# + .trim() + ); + } +} -- 2.42.0