Finish to convert NW filter Lib structures into REST structures

This commit is contained in:
Pierre HUBERT 2023-12-29 12:45:03 +01:00
parent 246f5ef842
commit 61c567846d
2 changed files with 327 additions and 95 deletions

View File

@ -1,6 +1,6 @@
use crate::libvirt_lib_structures::XMLUuid; use crate::libvirt_lib_structures::XMLUuid;
use std::fmt::Display; use std::fmt::Display;
use std::net::IpAddr; use std::net::{Ipv4Addr, Ipv6Addr};
#[derive(serde::Serialize, serde::Deserialize, Debug)] #[derive(serde::Serialize, serde::Deserialize, Debug)]
#[serde(rename = "filterref")] #[serde(rename = "filterref")]
@ -20,27 +20,27 @@ pub struct NetworkFilterRuleProtocolMac {
rename(serialize = "@srcmacaddr"), rename(serialize = "@srcmacaddr"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
srcmacaddr: Option<String>, pub srcmacaddr: Option<String>,
#[serde( #[serde(
rename(serialize = "@srcmacmask"), rename(serialize = "@srcmacmask"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
srcmacmask: Option<String>, pub srcmacmask: Option<String>,
#[serde( #[serde(
rename(serialize = "@dstmacaddr"), rename(serialize = "@dstmacaddr"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
dstmacaddr: Option<String>, pub dstmacaddr: Option<String>,
#[serde( #[serde(
rename(serialize = "@dstmacmask"), rename(serialize = "@dstmacmask"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
dstmacmask: Option<String>, pub dstmacmask: Option<String>,
#[serde( #[serde(
rename(serialize = "@comment"), rename(serialize = "@comment"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
comment: Option<String>, pub comment: Option<String>,
} }
#[derive(serde::Serialize, serde::Deserialize, Debug)] #[derive(serde::Serialize, serde::Deserialize, Debug)]
@ -50,48 +50,48 @@ pub struct NetworkFilterRuleProtocolArp {
rename(serialize = "@srcmacaddr"), rename(serialize = "@srcmacaddr"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
srcmacaddr: Option<String>, pub srcmacaddr: Option<String>,
#[serde( #[serde(
rename(serialize = "@srcmacmask"), rename(serialize = "@srcmacmask"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
srcmacmask: Option<String>, pub srcmacmask: Option<String>,
#[serde( #[serde(
rename(serialize = "@dstmacaddr"), rename(serialize = "@dstmacaddr"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
dstmacaddr: Option<String>, pub dstmacaddr: Option<String>,
#[serde( #[serde(
rename(serialize = "@dstmacmask"), rename(serialize = "@dstmacmask"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
dstmacmask: Option<String>, pub dstmacmask: Option<String>,
#[serde( #[serde(
rename(serialize = "@arpsrcipaddr"), rename(serialize = "@arpsrcipaddr"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
arpsrcipaddr: Option<String>, pub arpsrcipaddr: Option<String>,
#[serde( #[serde(
rename(serialize = "@arpsrcipmask"), rename(serialize = "@arpsrcipmask"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
arpsrcipmask: Option<u8>, pub arpsrcipmask: Option<u8>,
#[serde( #[serde(
rename(serialize = "@arpdstipaddr"), rename(serialize = "@arpdstipaddr"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
arpdstipaddr: Option<String>, pub arpdstipaddr: Option<String>,
#[serde( #[serde(
rename(serialize = "@arpdstipmask"), rename(serialize = "@arpdstipmask"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
arpdstipmask: Option<u8>, pub arpdstipmask: Option<u8>,
#[serde( #[serde(
rename(serialize = "@comment"), rename(serialize = "@comment"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
comment: Option<String>, pub comment: Option<String>,
} }
#[derive(serde::Serialize, serde::Deserialize, Debug)] #[derive(serde::Serialize, serde::Deserialize, Debug)]
@ -101,130 +101,130 @@ pub struct NetworkFilterRuleProtocolIpvx {
rename(serialize = "@srcmacaddr"), rename(serialize = "@srcmacaddr"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
srcmacaddr: Option<String>, pub srcmacaddr: Option<String>,
#[serde( #[serde(
rename(serialize = "@srcmacmask"), rename(serialize = "@srcmacmask"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
srcmacmask: Option<String>, pub srcmacmask: Option<String>,
#[serde( #[serde(
rename(serialize = "@dstmacaddr"), rename(serialize = "@dstmacaddr"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
dstmacaddr: Option<String>, pub dstmacaddr: Option<String>,
#[serde( #[serde(
rename(serialize = "@dstmacmask"), rename(serialize = "@dstmacmask"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
dstmacmask: Option<String>, pub dstmacmask: Option<String>,
#[serde( #[serde(
rename(serialize = "@srcipaddr"), rename(serialize = "@srcipaddr"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
srcipaddr: Option<String>, pub srcipaddr: Option<String>,
#[serde( #[serde(
rename(serialize = "@srcipmask"), rename(serialize = "@srcipmask"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
srcipmask: Option<u8>, pub srcipmask: Option<u8>,
#[serde( #[serde(
rename(serialize = "@dstipaddr"), rename(serialize = "@dstipaddr"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
dstipaddr: Option<String>, pub dstipaddr: Option<String>,
#[serde( #[serde(
rename(serialize = "@dstipmask"), rename(serialize = "@dstipmask"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
dstipmask: Option<u8>, pub dstipmask: Option<u8>,
#[serde( #[serde(
rename(serialize = "@comment"), rename(serialize = "@comment"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
comment: Option<String>, pub comment: Option<String>,
} }
#[derive(serde::Serialize, serde::Deserialize, Debug)] #[derive(serde::Serialize, serde::Deserialize, Debug)]
#[serde(rename = "layer4")] #[serde(rename = "layer4")]
pub struct NetworkFilterRuleProtocolLayer4 { pub struct NetworkFilterRuleProtocolLayer4<IPv> {
#[serde( #[serde(
rename(serialize = "@srcmacaddr"), rename(serialize = "@srcmacaddr"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
srcmacaddr: Option<String>, pub srcmacaddr: Option<String>,
#[serde( #[serde(
rename(serialize = "@srcipaddr"), rename(serialize = "@srcipaddr"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
srcipaddr: Option<IpAddr>, pub srcipaddr: Option<IPv>,
#[serde( #[serde(
rename(serialize = "@srcipmask"), rename(serialize = "@srcipmask"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
srcipmask: Option<u8>, pub srcipmask: Option<u8>,
#[serde( #[serde(
rename(serialize = "@dstipaddr"), rename(serialize = "@dstipaddr"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
dstipaddr: Option<IpAddr>, pub dstipaddr: Option<IPv>,
#[serde( #[serde(
rename(serialize = "@dstipmask"), rename(serialize = "@dstipmask"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
dstipmask: Option<u8>, pub dstipmask: Option<u8>,
/// Start of range of source IP address /// Start of range of source IP address
#[serde( #[serde(
rename(serialize = "@srcipfrom"), rename(serialize = "@srcipfrom"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
srcipfrom: Option<IpAddr>, pub srcipfrom: Option<IPv>,
/// End of range of source IP address /// End of range of source IP address
#[serde( #[serde(
rename(serialize = "@srcipto"), rename(serialize = "@srcipto"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
srcipto: Option<IpAddr>, pub srcipto: Option<IPv>,
/// Start of range of destination IP address /// Start of range of destination IP address
#[serde( #[serde(
rename(serialize = "@dstipfrom"), rename(serialize = "@dstipfrom"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
dstipfrom: Option<IpAddr>, pub dstipfrom: Option<IPv>,
/// End of range of destination IP address /// End of range of destination IP address
#[serde( #[serde(
rename(serialize = "@dstipto"), rename(serialize = "@dstipto"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
dstipto: Option<IpAddr>, pub dstipto: Option<IPv>,
#[serde( #[serde(
rename(serialize = "@srcportstart"), rename(serialize = "@srcportstart"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
srcportstart: Option<u16>, pub srcportstart: Option<u16>,
#[serde( #[serde(
rename(serialize = "@srcportend"), rename(serialize = "@srcportend"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
srcportend: Option<u16>, pub srcportend: Option<u16>,
#[serde( #[serde(
rename(serialize = "@dstportstart"), rename(serialize = "@dstportstart"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
dstportstart: Option<u16>, pub dstportstart: Option<u16>,
#[serde( #[serde(
rename(serialize = "@dstportend"), rename(serialize = "@dstportend"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
dstportend: Option<u16>, pub dstportend: Option<u16>,
#[serde(rename(serialize = "@state"), skip_serializing_if = "Option::is_none")] #[serde(rename(serialize = "@state"), skip_serializing_if = "Option::is_none")]
state: Option<String>, pub state: Option<String>,
#[serde( #[serde(
rename(serialize = "@comment"), rename(serialize = "@comment"),
skip_serializing_if = "Option::is_none" skip_serializing_if = "Option::is_none"
)] )]
comment: Option<String>, pub comment: Option<String>,
} }
#[derive(serde::Serialize, serde::Deserialize, Debug)] #[derive(serde::Serialize, serde::Deserialize, Debug)]
@ -249,6 +249,10 @@ pub struct NetworkFilterRuleXML {
#[serde(default, rename = "arp", skip_serializing_if = "Vec::is_empty")] #[serde(default, rename = "arp", skip_serializing_if = "Vec::is_empty")]
pub arp_rules: Vec<NetworkFilterRuleProtocolArp>, pub arp_rules: Vec<NetworkFilterRuleProtocolArp>,
/// Match rarp protocol
#[serde(default, rename = "arp", skip_serializing_if = "Vec::is_empty")]
pub rarp_rules: Vec<NetworkFilterRuleProtocolArp>,
/// Match IPv4 protocol /// Match IPv4 protocol
#[serde(default, rename = "ip", skip_serializing_if = "Vec::is_empty")] #[serde(default, rename = "ip", skip_serializing_if = "Vec::is_empty")]
pub ipv4_rules: Vec<NetworkFilterRuleProtocolIpvx>, pub ipv4_rules: Vec<NetworkFilterRuleProtocolIpvx>,
@ -259,15 +263,35 @@ pub struct NetworkFilterRuleXML {
/// Match TCP protocol /// Match TCP protocol
#[serde(default, rename = "tcp", skip_serializing_if = "Vec::is_empty")] #[serde(default, rename = "tcp", skip_serializing_if = "Vec::is_empty")]
pub tcp_rules: Vec<NetworkFilterRuleProtocolLayer4>, pub tcp_rules: Vec<NetworkFilterRuleProtocolLayer4<Ipv4Addr>>,
/// Match UDP protocol /// Match UDP protocol
#[serde(default, rename = "udp", skip_serializing_if = "Vec::is_empty")] #[serde(default, rename = "udp", skip_serializing_if = "Vec::is_empty")]
pub udp_rules: Vec<NetworkFilterRuleProtocolLayer4>, pub udp_rules: Vec<NetworkFilterRuleProtocolLayer4<Ipv4Addr>>,
/// Match SCTP protocol /// Match SCTP protocol
#[serde(default, rename = "sctp", skip_serializing_if = "Vec::is_empty")] #[serde(default, rename = "sctp", skip_serializing_if = "Vec::is_empty")]
pub sctp_rules: Vec<NetworkFilterRuleProtocolLayer4>, pub sctp_rules: Vec<NetworkFilterRuleProtocolLayer4<Ipv4Addr>>,
/// Match ICMP protocol
#[serde(default, rename = "icmp", skip_serializing_if = "Vec::is_empty")]
pub imcp_rules: Vec<NetworkFilterRuleProtocolLayer4<Ipv4Addr>>,
/// Match TCP IPv6 protocol
#[serde(default, rename = "tcp-ipv6", skip_serializing_if = "Vec::is_empty")]
pub tcp_ipv6_rules: Vec<NetworkFilterRuleProtocolLayer4<Ipv6Addr>>,
/// Match UDP IPv6 protocol
#[serde(default, rename = "udp-ipv6", skip_serializing_if = "Vec::is_empty")]
pub udp_ipv6_rules: Vec<NetworkFilterRuleProtocolLayer4<Ipv6Addr>>,
/// Match SCTP IPv6 protocol
#[serde(default, rename = "sctp-ipv6", skip_serializing_if = "Vec::is_empty")]
pub sctp_ipv6_rules: Vec<NetworkFilterRuleProtocolLayer4<Ipv6Addr>>,
/// Match ICMP IPv6 protocol
#[serde(default, rename = "icmpv6", skip_serializing_if = "Vec::is_empty")]
pub imcp_ipv6_rules: Vec<NetworkFilterRuleProtocolLayer4<Ipv6Addr>>,
} }
#[derive(serde::Serialize, serde::Deserialize, Debug)] #[derive(serde::Serialize, serde::Deserialize, Debug)]

View File

@ -1,7 +1,10 @@
use crate::libvirt_lib_structures::nwfilter::NetworkFilterXML; use crate::libvirt_lib_structures::nwfilter::{
NetworkFilterRuleProtocolAll, NetworkFilterRuleProtocolArp, NetworkFilterRuleProtocolIpvx,
NetworkFilterRuleProtocolLayer4, NetworkFilterRuleProtocolMac, NetworkFilterXML,
};
use crate::libvirt_lib_structures::XMLUuid; use crate::libvirt_lib_structures::XMLUuid;
use crate::libvirt_rest_structures::LibVirtStructError; use crate::libvirt_rest_structures::LibVirtStructError;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use std::net::{Ipv4Addr, Ipv6Addr};
#[derive(serde::Serialize, serde::Deserialize, Debug, Copy, Clone)] #[derive(serde::Serialize, serde::Deserialize, Debug, Copy, Clone)]
pub enum NetworkFilterChainProtocol { pub enum NetworkFilterChainProtocol {
@ -30,7 +33,7 @@ impl NetworkFilterChainProtocol {
return Err(LibVirtStructError::ParseFilteringChain(format!( return Err(LibVirtStructError::ParseFilteringChain(format!(
"Unknown filtering chain: {xml}! " "Unknown filtering chain: {xml}! "
)) ))
.into()) .into());
} }
}) })
} }
@ -95,12 +98,187 @@ pub struct NetworkFilter {
} }
impl NetworkFilter { impl NetworkFilter {
fn process_all_rule(_n: &NetworkFilterRuleProtocolAll) -> NetworkFilterSelector {
NetworkFilterSelector::All
}
fn process_mac_rule(n: &NetworkFilterRuleProtocolMac) -> NetworkFilterSelector {
NetworkFilterSelector::Mac {
src_mac_addr: n.srcmacaddr.clone(),
src_mac_mask: n.srcmacmask.clone(),
dst_mac_addr: n.dstmacaddr.clone(),
dst_mac_mask: n.dstmacmask.clone(),
comment: n.comment.clone(),
}
}
fn process_arp_rule(n: &NetworkFilterRuleProtocolArp) -> NetworkSelectorARP {
NetworkSelectorARP {
srcmacaddr: n.srcmacaddr.clone(),
srcmacmask: n.srcmacmask.clone(),
dstmacaddr: n.dstmacaddr.clone(),
dstmacmask: n.dstmacmask.clone(),
arpsrcipaddr: n.arpsrcipaddr.clone(),
arpsrcipmask: n.arpsrcipmask,
arpdstipaddr: n.arpdstipaddr.clone(),
arpdstipmask: n.arpdstipmask,
comment: n.comment.clone(),
}
}
fn process_ip_rule(n: &NetworkFilterRuleProtocolIpvx) -> NetworkFilterSelectorIP {
NetworkFilterSelectorIP {
srcmacaddr: n.srcmacaddr.clone(),
srcmacmask: n.srcmacmask.clone(),
dstmacaddr: n.dstmacaddr.clone(),
dstmacmask: n.dstmacmask.clone(),
srcipaddr: n.srcipaddr.clone(),
srcipmask: n.srcipmask,
dstipaddr: n.dstipaddr.clone(),
dstipmask: n.dstipmask,
comment: n.comment.clone(),
}
}
fn process_layer4_rule<IPv: Copy>(
n: &NetworkFilterRuleProtocolLayer4<IPv>,
) -> anyhow::Result<NetworkSelectorLayer4<IPv>> {
Ok(NetworkSelectorLayer4 {
srcmacaddr: n.srcmacaddr.clone(),
srcipaddr: n.srcipaddr,
srcipmask: n.srcipmask,
dstipaddr: n.dstipaddr,
dstipmask: n.dstipmask,
srcipfrom: n.srcipfrom,
srcipto: n.srcipto,
dstipfrom: n.dstipfrom,
dstipto: n.dstipto,
srcportstart: n.srcportstart,
srcportend: n.srcportend,
dstportstart: n.dstportstart,
dstportend: n.dstportend,
state: n.state.as_deref().map(Layer4State::from_xml).transpose()?,
comment: n.comment.clone(),
})
}
pub fn from_xml(xml: NetworkFilterXML) -> anyhow::Result<Self> { pub fn from_xml(xml: NetworkFilterXML) -> anyhow::Result<Self> {
let mut rules = Vec::with_capacity(xml.rules.len()); let mut rules = Vec::with_capacity(xml.rules.len());
for rule in &xml.rules { for rule in &xml.rules {
let mut selectors = Vec::new(); let mut selectors = Vec::new();
// TODO : add other selectors // All selector
selectors.append(&mut rule.all.iter().map(Self::process_all_rule).collect());
// Mac rules
selectors.append(&mut rule.mac_rules.iter().map(Self::process_mac_rule).collect());
// ARP - RARP rules
selectors.append(
&mut rule
.arp_rules
.iter()
.map(|r| NetworkFilterSelector::Arp(Self::process_arp_rule(r)))
.collect(),
);
selectors.append(
&mut rule
.rarp_rules
.iter()
.map(|r| NetworkFilterSelector::Rarp(Self::process_arp_rule(r)))
.collect(),
);
// IPv4 - IPv6 rules
selectors.append(
&mut rule
.ipv4_rules
.iter()
.map(|r| NetworkFilterSelector::IPv4(Self::process_ip_rule(r)))
.collect(),
);
selectors.append(
&mut rule
.ipv6_rules
.iter()
.map(|r| NetworkFilterSelector::IPv6(Self::process_ip_rule(r)))
.collect(),
);
// Layer 4 protocols
selectors.append(
&mut rule
.tcp_rules
.iter()
.map(|r| Ok(NetworkFilterSelector::TCP(Self::process_layer4_rule(r)?)))
.collect::<Result<Vec<_>, anyhow::Error>>()?,
);
selectors.append(
&mut rule
.udp_rules
.iter()
.map(|r| Ok(NetworkFilterSelector::UDP(Self::process_layer4_rule(r)?)))
.collect::<Result<Vec<_>, anyhow::Error>>()?,
);
selectors.append(
&mut rule
.sctp_rules
.iter()
.map(|r| Ok(NetworkFilterSelector::SCTP(Self::process_layer4_rule(r)?)))
.collect::<Result<Vec<_>, anyhow::Error>>()?,
);
selectors.append(
&mut rule
.imcp_rules
.iter()
.map(|r| Ok(NetworkFilterSelector::ICMP(Self::process_layer4_rule(r)?)))
.collect::<Result<Vec<_>, anyhow::Error>>()?,
);
selectors.append(
&mut rule
.tcp_ipv6_rules
.iter()
.map(|r| {
Ok(NetworkFilterSelector::TCPipv6(Self::process_layer4_rule(
r,
)?))
})
.collect::<Result<Vec<_>, anyhow::Error>>()?,
);
selectors.append(
&mut rule
.udp_ipv6_rules
.iter()
.map(|r| {
Ok(NetworkFilterSelector::UDPipv6(Self::process_layer4_rule(
r,
)?))
})
.collect::<Result<Vec<_>, anyhow::Error>>()?,
);
selectors.append(
&mut rule
.sctp_ipv6_rules
.iter()
.map(|r| {
Ok(NetworkFilterSelector::SCTPipv6(Self::process_layer4_rule(
r,
)?))
})
.collect::<Result<Vec<_>, anyhow::Error>>()?,
);
selectors.append(
&mut rule
.imcp_ipv6_rules
.iter()
.map(|r| {
Ok(NetworkFilterSelector::ICMPipv6(Self::process_layer4_rule(
r,
)?))
})
.collect::<Result<Vec<_>, anyhow::Error>>()?,
);
rules.push(NetworkFilterRule { rules.push(NetworkFilterRule {
action: NetworkFilterAction::from_xml(&rule.action)?, action: NetworkFilterAction::from_xml(&rule.action)?,
@ -152,7 +330,7 @@ impl NetworkFilterAction {
return Err(LibVirtStructError::ParseFilteringChain(format!( return Err(LibVirtStructError::ParseFilteringChain(format!(
"Unkown filter action {s}!" "Unkown filter action {s}!"
)) ))
.into()) .into());
} }
}) })
} }
@ -186,7 +364,7 @@ impl NetworkFilterDirection {
return Err(LibVirtStructError::ParseFilteringChain(format!( return Err(LibVirtStructError::ParseFilteringChain(format!(
"Unkown filter direction {s}!" "Unkown filter direction {s}!"
)) ))
.into()) .into());
} }
}) })
} }
@ -210,28 +388,81 @@ pub enum Layer4State {
NONE, NONE,
} }
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)] impl Layer4State {
pub enum Layer4Type { pub fn from_xml(xml: &str) -> anyhow::Result<Self> {
TCP, Ok(match xml {
UDP, "NEW" => Self::NEW,
SCTP, "ESTABLISHED" => Self::ESTABLISHED,
ICMP, "RELATED" => Self::RELATED,
TCPipv6, "INVALID" => Self::INVALID,
UDPipv6, "NONE" => Self::NONE,
SCTPipv6, s => {
ICMPipv6, return Err(LibVirtStructError::ParseFilteringChain(format!(
"Unkown layer4 state '{s}'!"
))
.into());
}
})
}
pub fn to_xml(&self) -> String {
match self {
Self::NEW => "NEW",
Self::ESTABLISHED => "ESTABLISHED",
Self::RELATED => "RELATED",
Self::INVALID => "INVALID",
Self::NONE => "NONE",
}
.to_string()
}
} }
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)] #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct NetworkFilterSelectorIP<IPv> { pub struct NetworkFilterSelectorIP {
srcmacaddr: Option<String>, srcmacaddr: Option<String>,
srcmacmask: Option<String>, srcmacmask: Option<String>,
dstmacaddr: Option<String>, dstmacaddr: Option<String>,
dstmacmask: Option<String>, dstmacmask: Option<String>,
srcipaddr: Option<String>,
srcipmask: Option<u8>,
dstipaddr: Option<String>,
dstipmask: Option<u8>,
comment: Option<String>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct NetworkSelectorARP {
srcmacaddr: Option<String>,
srcmacmask: Option<String>,
dstmacaddr: Option<String>,
dstmacmask: Option<String>,
arpsrcipaddr: Option<String>,
arpsrcipmask: Option<u8>,
arpdstipaddr: Option<String>,
arpdstipmask: Option<u8>,
comment: Option<String>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct NetworkSelectorLayer4<IPv> {
srcmacaddr: Option<String>,
srcipaddr: Option<IPv>, srcipaddr: Option<IPv>,
srcipmask: Option<u8>, srcipmask: Option<u8>,
dstipaddr: Option<IPv>, dstipaddr: Option<IPv>,
dstipmask: Option<u8>, dstipmask: Option<u8>,
/// Start of range of source IP address
srcipfrom: Option<IPv>,
/// End of range of source IP address
srcipto: Option<IPv>,
/// Start of range of destination IP address
dstipfrom: Option<IPv>,
/// End of range of destination IP address
dstipto: Option<IPv>,
srcportstart: Option<u16>,
srcportend: Option<u16>,
dstportstart: Option<u16>,
dstportend: Option<u16>,
state: Option<Layer4State>,
comment: Option<String>, comment: Option<String>,
} }
@ -245,41 +476,18 @@ pub enum NetworkFilterSelector {
dst_mac_mask: Option<String>, dst_mac_mask: Option<String>,
comment: Option<String>, comment: Option<String>,
}, },
Arp { Arp(NetworkSelectorARP),
srcmacaddr: Option<String>, Rarp(NetworkSelectorARP),
srcmacmask: Option<String>, IPv4(NetworkFilterSelectorIP),
dstmacaddr: Option<String>, IPv6(NetworkFilterSelectorIP),
dstmacmask: Option<String>, TCP(NetworkSelectorLayer4<Ipv4Addr>),
arpsrcipaddr: Option<IpAddr>, UDP(NetworkSelectorLayer4<Ipv4Addr>),
arpsrcipmask: Option<u8>, SCTP(NetworkSelectorLayer4<Ipv4Addr>),
arpdstipaddr: Option<IpAddr>, ICMP(NetworkSelectorLayer4<Ipv4Addr>),
arpdstipmask: Option<u8>, TCPipv6(NetworkSelectorLayer4<Ipv6Addr>),
comment: Option<String>, UDPipv6(NetworkSelectorLayer4<Ipv6Addr>),
}, SCTPipv6(NetworkSelectorLayer4<Ipv6Addr>),
IPv4(NetworkFilterSelectorIP<Ipv4Addr>), ICMPipv6(NetworkSelectorLayer4<Ipv6Addr>),
IPv6(NetworkFilterSelectorIP<Ipv6Addr>),
Layer4 {
r#type: Layer4Type,
srcmacaddr: Option<String>,
srcipaddr: Option<IpAddr>,
srcipmask: Option<u8>,
dstipaddr: Option<IpAddr>,
dstipmask: Option<u8>,
/// Start of range of source IP address
srcipfrom: Option<IpAddr>,
/// End of range of source IP address
srcipto: Option<IpAddr>,
/// Start of range of destination IP address
dstipfrom: Option<IpAddr>,
/// End of range of destination IP address
dstipto: Option<IpAddr>,
srcportstart: Option<u16>,
srcportend: Option<u16>,
dstportstart: Option<u16>,
dstportend: Option<u16>,
state: Option<Layer4State>,
comment: Option<String>,
},
} }
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)] #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]