dg_network_manager 1.0.0

Network Manager DBUS API
Documentation
use super::DeviceClient;
use std::io::{Error, ErrorKind};
use std::sync::Arc;
use zbus::proxy::CacheProperties;
use zbus::zvariant::OwnedObjectPath;
use zbus::{Connection, Result as ZResult, proxy};

#[proxy(
    interface = "org.freedesktop.NetworkManager.Device.Vxlan",
    default_service = "org.freedesktop.NetworkManager"
)]
pub trait Vxlan {
    // Properties
    #[zbus(property)]
    fn parent(&self) -> ZResult<OwnedObjectPath>;

    #[zbus(property)]
    fn hw_address(&self) -> ZResult<String>;

    #[zbus(property)]
    fn id(&self) -> ZResult<u32>;

    #[zbus(property)]
    fn group(&self) -> ZResult<String>;

    #[zbus(property)]
    fn local(&self) -> ZResult<String>;

    #[zbus(property)]
    fn tos(&self) -> ZResult<u8>;

    #[zbus(property)]
    fn ttl(&self) -> ZResult<u8>;

    #[zbus(property)]
    fn learning(&self) -> ZResult<bool>;

    #[zbus(property)]
    fn ageing(&self) -> ZResult<u32>;

    #[zbus(property)]
    fn limit(&self) -> ZResult<u32>;

    #[zbus(property)]
    fn dst_port(&self) -> ZResult<u16>;

    #[zbus(property)]
    fn src_port_min(&self) -> ZResult<u16>;

    #[zbus(property)]
    fn src_port_max(&self) -> ZResult<u16>;

    #[zbus(property)]
    fn proxy(&self) -> ZResult<bool>;

    #[zbus(property)]
    fn rsc(&self) -> ZResult<bool>;

    #[zbus(property)]
    fn l2miss(&self) -> ZResult<bool>;

    #[zbus(property)]
    fn l3miss(&self) -> ZResult<bool>;
}

pub struct VxlanClient {
    device: DeviceClient,
    proxy: VxlanProxy<'static>,
}

impl VxlanClient {
    pub async fn new(connection: Arc<Connection>, service_path: String) -> Result<Self, Error> {
        let device = DeviceClient::new(connection.clone(), service_path.clone()).await?;

        let proxy = VxlanProxy::builder(&connection)
            .path(service_path)
            .map_err(|e| Error::new(ErrorKind::InvalidInput, e.to_string()))?
            .cache_properties(CacheProperties::Yes)
            .build()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;

        // Verify we can access vxlan-specific properties
        proxy
            .id()
            .await
            .map_err(|e| Error::new(ErrorKind::NotFound, e.to_string()))?;

        Ok(Self { device, proxy })
    }

    // Forward common device methods to the base device client
    pub fn service_path(&self) -> &str {
        self.device.service_path()
    }

    pub async fn interface(&self) -> Result<String, Error> {
        self.device.interface().await
    }

    pub async fn disconnect(&self) -> Result<(), Error> {
        self.device.disconnect().await
    }

    // Vxlan-specific methods
    pub async fn parent(&self) -> Result<OwnedObjectPath, Error> {
        self.proxy
            .parent()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    pub async fn hw_address(&self) -> Result<String, Error> {
        self.proxy
            .hw_address()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    pub async fn id(&self) -> Result<u32, Error> {
        self.proxy
            .id()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    pub async fn group(&self) -> Result<String, Error> {
        self.proxy
            .group()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    pub async fn local(&self) -> Result<String, Error> {
        self.proxy
            .local()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    pub async fn tos(&self) -> Result<u8, Error> {
        self.proxy
            .tos()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    pub async fn ttl(&self) -> Result<u8, Error> {
        self.proxy
            .ttl()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    pub async fn learning(&self) -> Result<bool, Error> {
        self.proxy
            .learning()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    pub async fn ageing(&self) -> Result<u32, Error> {
        self.proxy
            .ageing()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    pub async fn limit(&self) -> Result<u32, Error> {
        self.proxy
            .limit()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    pub async fn dst_port(&self) -> Result<u16, Error> {
        self.proxy
            .dst_port()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    pub async fn src_port_min(&self) -> Result<u16, Error> {
        self.proxy
            .src_port_min()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    pub async fn src_port_max(&self) -> Result<u16, Error> {
        self.proxy
            .src_port_max()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    pub async fn proxy(&self) -> Result<bool, Error> {
        self.proxy
            .proxy()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    pub async fn rsc(&self) -> Result<bool, Error> {
        self.proxy
            .rsc()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    pub async fn l2miss(&self) -> Result<bool, Error> {
        self.proxy
            .l2miss()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    pub async fn l3miss(&self) -> Result<bool, Error> {
        self.proxy
            .l3miss()
            .await
            .map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
    }

    // Helper method to get the parent device
    pub async fn get_parent_device(
        &self,
        connection: Arc<Connection>,
    ) -> Result<super::Device, Error> {
        let parent_path = self.parent().await?;
        super::Device::new(connection, parent_path.to_string()).await
    }
}