[pve-devel] [PATCH proxmox v4 3/5] network-types: add api types for ipv4/6

Wolfgang Bumiller w.bumiller at proxmox.com
Thu Jul 3 15:18:21 CEST 2025


On Wed, Jul 02, 2025 at 04:49:48PM +0200, Gabriel Goller wrote:
> From: Stefan Hanreich <s.hanreich at proxmox.com>
> 
> Add two types that transparently wrap the std structs for IPv4 and
> IPv6 addresses as well as MacAddress, so they can be used directly in
> structs with the API macro. Similar to their CIDR counterparts, they
> have a StringSchema and are (de-)serialized via the respective
> FromStr and Display implementations.
> 
> Signed-off-by: Stefan Hanreich <s.hanreich at proxmox.com>
> ---
>  proxmox-network-types/src/ip_address.rs | 126 ++++++++++++++++++++++++
>  1 file changed, 126 insertions(+)
> 
> diff --git a/proxmox-network-types/src/ip_address.rs b/proxmox-network-types/src/ip_address.rs
> index 827141b9e86d..8c21453a36b4 100644
> --- a/proxmox-network-types/src/ip_address.rs
> +++ b/proxmox-network-types/src/ip_address.rs
> @@ -11,6 +11,132 @@ use proxmox_schema::{ApiType, Schema, UpdaterType};
>  #[cfg(feature = "api-types")]
>  use proxmox_schema::api_types::{CIDR_SCHEMA, CIDR_V4_SCHEMA, CIDR_V6_SCHEMA};
>  
> +#[cfg(feature = "api-types")]
> +pub mod api_types {
> +    use std::net::AddrParseError;
> +    use std::ops::{Deref, DerefMut};
> +
> +    use proxmox_schema::api_types::IP_V6_SCHEMA;
> +    use proxmox_schema::{api_types::IP_V4_SCHEMA, ApiType, UpdaterType};
> +    use serde_with::{DeserializeFromStr, SerializeDisplay};
> +
> +    #[derive(
> +        Debug,
> +        Clone,
> +        Copy,
> +        Eq,
> +        PartialEq,
> +        Ord,
> +        PartialOrd,
> +        DeserializeFromStr,
> +        SerializeDisplay,
> +        Hash,
> +    )]
> +    #[repr(transparent)]
> +    pub struct Ipv4Addr(std::net::Ipv4Addr);

^ May as well have the inside be `pub`.
(We already document it as `repr(transparent)`)
Or do we have any reasons against this?

> +
> +    impl ApiType for Ipv4Addr {
> +        const API_SCHEMA: proxmox_schema::Schema = IP_V4_SCHEMA;
> +    }
> +
> +    impl UpdaterType for Ipv4Addr {
> +        type Updater = Option<Ipv4Addr>;
> +    }
> +
> +    impl Deref for Ipv4Addr {
> +        type Target = std::net::Ipv4Addr;
> +
> +        fn deref(&self) -> &Self::Target {
> +            &self.0
> +        }
> +    }
> +
> +    impl DerefMut for Ipv4Addr {
> +        fn deref_mut(&mut self) -> &mut Self::Target {
> +            &mut self.0
> +        }
> +    }
> +
> +    impl std::str::FromStr for Ipv4Addr {
> +        type Err = AddrParseError;
> +
> +        fn from_str(value: &str) -> Result<Self, Self::Err> {
> +            let ip_address = std::net::Ipv4Addr::from_str(value)?;
> +            Ok(Self(ip_address))
> +        }
> +    }
> +
> +    impl std::fmt::Display for Ipv4Addr {
> +        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
> +            self.0.fmt(f)
> +        }
> +    }
> +
> +    impl From<std::net::Ipv4Addr> for Ipv4Addr {
> +        fn from(value: std::net::Ipv4Addr) -> Self {
> +            Self(value)
> +        }
> +    }
> +
> +    #[derive(
> +        Debug,
> +        Clone,
> +        Copy,
> +        Eq,
> +        PartialEq,
> +        Ord,
> +        PartialOrd,
> +        DeserializeFromStr,
> +        SerializeDisplay,
> +        Hash,
> +    )]
> +    #[repr(transparent)]
> +    pub struct Ipv6Addr(std::net::Ipv6Addr);

^ Same

> +
> +    impl ApiType for Ipv6Addr {
> +        const API_SCHEMA: proxmox_schema::Schema = IP_V6_SCHEMA;
> +    }
> +
> +    impl UpdaterType for Ipv6Addr {
> +        type Updater = Option<Ipv6Addr>;
> +    }
> +
> +    impl Deref for Ipv6Addr {
> +        type Target = std::net::Ipv6Addr;
> +
> +        fn deref(&self) -> &Self::Target {
> +            &self.0
> +        }
> +    }
> +
> +    impl DerefMut for Ipv6Addr {
> +        fn deref_mut(&mut self) -> &mut Self::Target {
> +            &mut self.0
> +        }
> +    }
> +
> +    impl std::str::FromStr for Ipv6Addr {
> +        type Err = AddrParseError;
> +
> +        fn from_str(value: &str) -> Result<Self, Self::Err> {
> +            let ip_address = std::net::Ipv6Addr::from_str(value)?;
> +            Ok(Self(ip_address))
> +        }
> +    }
> +
> +    impl std::fmt::Display for Ipv6Addr {
> +        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
> +            self.0.fmt(f)
> +        }
> +    }
> +
> +    impl From<std::net::Ipv6Addr> for Ipv6Addr {
> +        fn from(value: std::net::Ipv6Addr) -> Self {
> +            Self(value)
> +        }
> +    }
> +}
> +
>  /// The family (v4 or v6)  of an IP address or CIDR prefix
>  #[derive(Clone, Copy, Debug, Eq, PartialEq)]
>  pub enum Family {
> -- 
> 2.39.5




More information about the pve-devel mailing list