From 433878a17f1adfcaf2618cdb6db852eb5ec436ec Mon Sep 17 00:00:00 2001 From: Clemens Famulla-Conrad Date: Mon, 27 Nov 2023 18:03:36 +0100 Subject: [PATCH] Add vlan model --- rust/agama-dbus-server/src/network/model.rs | 16 +++++ rust/agama-dbus-server/src/network/nm/dbus.rs | 61 +++++++++++++++++++ rust/agama-lib/src/network/types.rs | 2 + 3 files changed, 79 insertions(+) diff --git a/rust/agama-dbus-server/src/network/model.rs b/rust/agama-dbus-server/src/network/model.rs index 0205b2fe2b..69e34997ea 100644 --- a/rust/agama-dbus-server/src/network/model.rs +++ b/rust/agama-dbus-server/src/network/model.rs @@ -345,6 +345,7 @@ impl Connection { DeviceType::Loopback => ConnectionConfig::Loopback, DeviceType::Dummy => ConnectionConfig::Dummy, DeviceType::Bond => ConnectionConfig::Bond(Default::default()), + DeviceType::Vlan => ConnectionConfig::Vlan(Default::default()), }; Self { id, @@ -410,6 +411,7 @@ pub enum ConnectionConfig { Loopback, Dummy, Bond(BondConfig), + Vlan(VlanConfig), } impl From for ConnectionConfig { @@ -617,6 +619,20 @@ impl From<&IpRoute> for HashMap<&str, Value<'_>> { } } +#[derive(Debug, Default, PartialEq, Clone)] +pub enum VlanProtocol { + #[default] + Ieee802_1Q, + Ieee802Ad, +} + +#[derive(Debug, Default, PartialEq, Clone)] +pub struct VlanConfig { + pub parent: String, + pub id: u32, + pub protocol: VlanProtocol, +} + #[derive(Debug, Default, PartialEq, Clone)] pub struct WirelessConfig { pub mode: WirelessMode, diff --git a/rust/agama-dbus-server/src/network/nm/dbus.rs b/rust/agama-dbus-server/src/network/nm/dbus.rs index 3dc7846a38..004300d9e5 100644 --- a/rust/agama-dbus-server/src/network/nm/dbus.rs +++ b/rust/agama-dbus-server/src/network/nm/dbus.rs @@ -19,6 +19,7 @@ const WIRELESS_KEY: &str = "802-11-wireless"; const WIRELESS_SECURITY_KEY: &str = "802-11-wireless-security"; const LOOPBACK_KEY: &str = "loopback"; const DUMMY_KEY: &str = "dummy"; +const VLAN_KEY: &str = "vlan"; /// Converts a connection struct into a HashMap that can be sent over D-Bus. /// @@ -77,6 +78,10 @@ pub fn connection_to_dbus<'a>( ConnectionConfig::Dummy => { connection_dbus.insert("type", DUMMY_KEY.into()); } + ConnectionConfig::Vlan(vlan) => { + connection_dbus.insert("type", VLAN_KEY.into()); + result.extend(vlan_config_to_dbus(vlan)); + } _ => {} } @@ -100,6 +105,11 @@ pub fn connection_from_dbus(conn: OwnedNestedHash) -> Option { return Some(connection); } + if let Some(vlan_config) = vlan_config_from_dbus(&conn) { + connection.config = ConnectionConfig::Vlan(vlan_config); + return Some(connection); + } + if conn.get(DUMMY_KEY).is_some() { connection.config = ConnectionConfig::Dummy; return Some(connection); @@ -567,6 +577,57 @@ fn bond_config_from_dbus(conn: &OwnedNestedHash) -> Option { Some(bond) } +fn vlan_config_to_dbus(cfg: &VlanConfig) -> NestedHash { + let vlan: HashMap<&str, zvariant::Value> = HashMap::from([ + ("id", cfg.id.into()), + ("parent", cfg.parent.clone().into()), + ( + "protocol", + match cfg.protocol { + VlanProtocol::Ieee802_1Q => "802.1Q".into(), + VlanProtocol::Ieee802Ad => "802.1ad".into(), + }, + ), + ]); + + NestedHash::from([("vlan", vlan)]) +} + +fn vlan_config_from_dbus(conn: &OwnedNestedHash) -> Option { + let Some(vlan) = conn.get(VLAN_KEY) else { + return None; + }; + + let Some(id) = vlan.get("id") else { + return None; + }; + let id = id.downcast_ref::()?; + + let Some(parent) = vlan.get("parent") else { + return None; + }; + let parent: &str = parent.downcast_ref()?; + + let protocol = match vlan.get("protocol") { + Some(x) => { + let x: &str = x.downcast_ref()?; + if x == "802.1ad" { + VlanProtocol::Ieee802Ad + } else { + VlanProtocol::Ieee802_1Q + } + } + _ => VlanProtocol::Ieee802_1Q, + }; + + Some(VlanConfig { + id: *id, + parent: String::from(parent), + protocol, + ..Default::default() + }) +} + /// Determines whether a value is empty. /// /// TODO: Generalize for other kind of values, like dicts or arrays. diff --git a/rust/agama-lib/src/network/types.rs b/rust/agama-lib/src/network/types.rs index 5a14fe238e..6d26fc953d 100644 --- a/rust/agama-lib/src/network/types.rs +++ b/rust/agama-lib/src/network/types.rs @@ -38,6 +38,7 @@ pub enum DeviceType { Wireless = 2, Dummy = 3, Bond = 4, + Vlan = 5, } /// Bond mode @@ -139,6 +140,7 @@ impl TryFrom for DeviceType { 2 => Ok(DeviceType::Wireless), 3 => Ok(DeviceType::Dummy), 4 => Ok(DeviceType::Bond), + 5 => Ok(DeviceType::Vlan), _ => Err(InvalidDeviceType(value)), } }