Fix issue with network netmask handling

This commit is contained in:
Pierre HUBERT 2023-12-05 18:55:16 +01:00
parent e579a3aadd
commit 7bf4e87df1
4 changed files with 50 additions and 3 deletions

View File

@ -1387,6 +1387,15 @@ version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
[[package]]
name = "ipnetwork"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e"
dependencies = [
"serde",
]
[[package]]
name = "is-terminal"
version = "0.4.9"
@ -2569,6 +2578,7 @@ dependencies = [
"futures",
"futures-util",
"image",
"ipnetwork",
"lazy-regex",
"lazy_static",
"light-openid",

View File

@ -39,3 +39,4 @@ rand = "0.8.5"
bytes = "1.5.0"
tokio = "1.32.0"
futures = "0.3.28"
ipnetwork = "0.20.0"

View File

@ -259,6 +259,14 @@ pub struct NetworkDomainXML {
pub name: String,
}
fn invalid_prefix() -> u32 {
u32::MAX
}
fn invalid_ip() -> IpAddr {
IpAddr::V4(Ipv4Addr::BROADCAST)
}
/// Network ip information
#[derive(serde::Serialize, serde::Deserialize, Debug)]
#[serde(rename = "ip")]
@ -267,8 +275,17 @@ pub struct NetworkIPXML {
pub family: String,
#[serde(rename(serialize = "@address"))]
pub address: IpAddr,
#[serde(rename(serialize = "@prefix"))]
/// Network Prefix
#[serde(rename(serialize = "@prefix"), default = "invalid_prefix")]
pub prefix: u32,
/// Network Netmask. This field is never serialized, but because we can't know if LibVirt will
/// provide us netmask or prefix, we need to handle both of these fields
#[serde(
rename(serialize = "@netmask"),
default = "invalid_ip",
skip_serializing
)]
pub netmask: IpAddr,
pub dhcp: Option<NetworkDHCPXML>,
}

View File

@ -9,6 +9,7 @@ use crate::libvirt_lib_structures::{
use crate::libvirt_rest_structures::LibVirtStructError::StructureExtraction;
use crate::utils::disks_utils::Disk;
use crate::utils::files_utils;
use ipnetwork::{Ipv4Network, Ipv6Network};
use lazy_regex::regex;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::ops::{Div, Mul};
@ -381,6 +382,10 @@ impl NetworkInfo {
family: "ipv4".to_string(),
address: IpAddr::V4(ipv4.bridge_address),
prefix: ipv4.prefix,
netmask: Ipv4Network::new(ipv4.bridge_address, ipv4.prefix as u8)
.unwrap()
.mask()
.into(),
dhcp: ipv4.dhcp_range.map(|[start, end]| NetworkDHCPXML {
range: NetworkDHCPRangeXML {
start: IpAddr::V4(start),
@ -395,6 +400,10 @@ impl NetworkInfo {
family: "ipv6".to_string(),
address: IpAddr::V6(ipv6.bridge_address),
prefix: ipv6.prefix,
netmask: Ipv6Network::new(ipv6.bridge_address, ipv6.prefix as u8)
.unwrap()
.mask()
.into(),
dhcp: ipv6.dhcp_range.map(|[start, end]| NetworkDHCPXML {
range: NetworkDHCPRangeXML {
start: IpAddr::V6(start),
@ -443,7 +452,12 @@ impl NetworkInfo {
.find(|i| i.family != "ipv6")
.map(|i| IPV4Config {
bridge_address: extract_ipv4(i.address),
prefix: i.prefix,
prefix: match i.prefix {
u32::MAX => ipnetwork::ipv4_mask_to_prefix(extract_ipv4(i.netmask))
.expect("Failed to convert IPv4 netmask to network")
as u32,
p => p,
},
dhcp_range: i
.dhcp
.as_ref()
@ -455,7 +469,12 @@ impl NetworkInfo {
.find(|i| i.family == "ipv6")
.map(|i| IPV6Config {
bridge_address: extract_ipv6(i.address),
prefix: i.prefix,
prefix: match i.prefix {
u32::MAX => ipnetwork::ipv6_mask_to_prefix(extract_ipv6(i.netmask))
.expect("Failed to convert IPv6 netmask to network")
as u32,
p => p,
},
dhcp_range: i
.dhcp
.as_ref()