Finish to convert NW filter Lib structures into REST structures
This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
			
		||||
use crate::libvirt_lib_structures::XMLUuid;
 | 
			
		||||
use std::fmt::Display;
 | 
			
		||||
use std::net::IpAddr;
 | 
			
		||||
use std::net::{Ipv4Addr, Ipv6Addr};
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
 | 
			
		||||
#[serde(rename = "filterref")]
 | 
			
		||||
@@ -20,27 +20,27 @@ pub struct NetworkFilterRuleProtocolMac {
 | 
			
		||||
        rename(serialize = "@srcmacaddr"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    srcmacaddr: Option<String>,
 | 
			
		||||
    pub srcmacaddr: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@srcmacmask"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    srcmacmask: Option<String>,
 | 
			
		||||
    pub srcmacmask: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@dstmacaddr"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    dstmacaddr: Option<String>,
 | 
			
		||||
    pub dstmacaddr: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@dstmacmask"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    dstmacmask: Option<String>,
 | 
			
		||||
    pub dstmacmask: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@comment"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    comment: Option<String>,
 | 
			
		||||
    pub comment: Option<String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
 | 
			
		||||
@@ -50,48 +50,48 @@ pub struct NetworkFilterRuleProtocolArp {
 | 
			
		||||
        rename(serialize = "@srcmacaddr"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    srcmacaddr: Option<String>,
 | 
			
		||||
    pub srcmacaddr: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@srcmacmask"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    srcmacmask: Option<String>,
 | 
			
		||||
    pub srcmacmask: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@dstmacaddr"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    dstmacaddr: Option<String>,
 | 
			
		||||
    pub dstmacaddr: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@dstmacmask"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    dstmacmask: Option<String>,
 | 
			
		||||
    pub dstmacmask: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@arpsrcipaddr"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    arpsrcipaddr: Option<String>,
 | 
			
		||||
    pub arpsrcipaddr: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@arpsrcipmask"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    arpsrcipmask: Option<u8>,
 | 
			
		||||
    pub arpsrcipmask: Option<u8>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@arpdstipaddr"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    arpdstipaddr: Option<String>,
 | 
			
		||||
    pub arpdstipaddr: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@arpdstipmask"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    arpdstipmask: Option<u8>,
 | 
			
		||||
    pub arpdstipmask: Option<u8>,
 | 
			
		||||
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@comment"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    comment: Option<String>,
 | 
			
		||||
    pub comment: Option<String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
 | 
			
		||||
@@ -101,130 +101,130 @@ pub struct NetworkFilterRuleProtocolIpvx {
 | 
			
		||||
        rename(serialize = "@srcmacaddr"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    srcmacaddr: Option<String>,
 | 
			
		||||
    pub srcmacaddr: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@srcmacmask"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    srcmacmask: Option<String>,
 | 
			
		||||
    pub srcmacmask: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@dstmacaddr"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    dstmacaddr: Option<String>,
 | 
			
		||||
    pub dstmacaddr: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@dstmacmask"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    dstmacmask: Option<String>,
 | 
			
		||||
    pub dstmacmask: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@srcipaddr"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    srcipaddr: Option<String>,
 | 
			
		||||
    pub srcipaddr: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@srcipmask"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    srcipmask: Option<u8>,
 | 
			
		||||
    pub srcipmask: Option<u8>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@dstipaddr"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    dstipaddr: Option<String>,
 | 
			
		||||
    pub dstipaddr: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@dstipmask"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    dstipmask: Option<u8>,
 | 
			
		||||
    pub dstipmask: Option<u8>,
 | 
			
		||||
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@comment"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    comment: Option<String>,
 | 
			
		||||
    pub comment: Option<String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
 | 
			
		||||
#[serde(rename = "layer4")]
 | 
			
		||||
pub struct NetworkFilterRuleProtocolLayer4 {
 | 
			
		||||
pub struct NetworkFilterRuleProtocolLayer4<IPv> {
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@srcmacaddr"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    srcmacaddr: Option<String>,
 | 
			
		||||
    pub srcmacaddr: Option<String>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@srcipaddr"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    srcipaddr: Option<IpAddr>,
 | 
			
		||||
    pub srcipaddr: Option<IPv>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@srcipmask"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    srcipmask: Option<u8>,
 | 
			
		||||
    pub srcipmask: Option<u8>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@dstipaddr"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    dstipaddr: Option<IpAddr>,
 | 
			
		||||
    pub dstipaddr: Option<IPv>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@dstipmask"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    dstipmask: Option<u8>,
 | 
			
		||||
    pub dstipmask: Option<u8>,
 | 
			
		||||
    /// Start of range of source IP address
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@srcipfrom"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    srcipfrom: Option<IpAddr>,
 | 
			
		||||
    pub srcipfrom: Option<IPv>,
 | 
			
		||||
    /// End of range of source IP address
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@srcipto"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    srcipto: Option<IpAddr>,
 | 
			
		||||
    pub srcipto: Option<IPv>,
 | 
			
		||||
    /// Start of range of destination IP address
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@dstipfrom"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    dstipfrom: Option<IpAddr>,
 | 
			
		||||
    pub dstipfrom: Option<IPv>,
 | 
			
		||||
    /// End of range of destination IP address
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@dstipto"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    dstipto: Option<IpAddr>,
 | 
			
		||||
    pub dstipto: Option<IPv>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@srcportstart"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    srcportstart: Option<u16>,
 | 
			
		||||
    pub srcportstart: Option<u16>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@srcportend"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    srcportend: Option<u16>,
 | 
			
		||||
    pub srcportend: Option<u16>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@dstportstart"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    dstportstart: Option<u16>,
 | 
			
		||||
    pub dstportstart: Option<u16>,
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@dstportend"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    dstportend: Option<u16>,
 | 
			
		||||
    pub dstportend: Option<u16>,
 | 
			
		||||
    #[serde(rename(serialize = "@state"), skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    state: Option<String>,
 | 
			
		||||
    pub state: Option<String>,
 | 
			
		||||
 | 
			
		||||
    #[serde(
 | 
			
		||||
        rename(serialize = "@comment"),
 | 
			
		||||
        skip_serializing_if = "Option::is_none"
 | 
			
		||||
    )]
 | 
			
		||||
    comment: Option<String>,
 | 
			
		||||
    pub comment: Option<String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
 | 
			
		||||
@@ -249,6 +249,10 @@ pub struct NetworkFilterRuleXML {
 | 
			
		||||
    #[serde(default, rename = "arp", skip_serializing_if = "Vec::is_empty")]
 | 
			
		||||
    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
 | 
			
		||||
    #[serde(default, rename = "ip", skip_serializing_if = "Vec::is_empty")]
 | 
			
		||||
    pub ipv4_rules: Vec<NetworkFilterRuleProtocolIpvx>,
 | 
			
		||||
@@ -259,15 +263,35 @@ pub struct NetworkFilterRuleXML {
 | 
			
		||||
 | 
			
		||||
    /// Match TCP protocol
 | 
			
		||||
    #[serde(default, rename = "tcp", skip_serializing_if = "Vec::is_empty")]
 | 
			
		||||
    pub tcp_rules: Vec<NetworkFilterRuleProtocolLayer4>,
 | 
			
		||||
    pub tcp_rules: Vec<NetworkFilterRuleProtocolLayer4<Ipv4Addr>>,
 | 
			
		||||
 | 
			
		||||
    /// Match UDP protocol
 | 
			
		||||
    #[serde(default, rename = "udp", skip_serializing_if = "Vec::is_empty")]
 | 
			
		||||
    pub udp_rules: Vec<NetworkFilterRuleProtocolLayer4>,
 | 
			
		||||
    pub udp_rules: Vec<NetworkFilterRuleProtocolLayer4<Ipv4Addr>>,
 | 
			
		||||
 | 
			
		||||
    /// Match SCTP protocol
 | 
			
		||||
    #[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)]
 | 
			
		||||
 
 | 
			
		||||
@@ -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_rest_structures::LibVirtStructError;
 | 
			
		||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
 | 
			
		||||
use std::net::{Ipv4Addr, Ipv6Addr};
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Copy, Clone)]
 | 
			
		||||
pub enum NetworkFilterChainProtocol {
 | 
			
		||||
@@ -30,7 +33,7 @@ impl NetworkFilterChainProtocol {
 | 
			
		||||
                return Err(LibVirtStructError::ParseFilteringChain(format!(
 | 
			
		||||
                    "Unknown filtering chain: {xml}! "
 | 
			
		||||
                ))
 | 
			
		||||
                .into())
 | 
			
		||||
                .into());
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
@@ -95,12 +98,187 @@ pub struct 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> {
 | 
			
		||||
        let mut rules = Vec::with_capacity(xml.rules.len());
 | 
			
		||||
        for rule in &xml.rules {
 | 
			
		||||
            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 {
 | 
			
		||||
                action: NetworkFilterAction::from_xml(&rule.action)?,
 | 
			
		||||
@@ -152,7 +330,7 @@ impl NetworkFilterAction {
 | 
			
		||||
                return Err(LibVirtStructError::ParseFilteringChain(format!(
 | 
			
		||||
                    "Unkown filter action {s}!"
 | 
			
		||||
                ))
 | 
			
		||||
                .into())
 | 
			
		||||
                .into());
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
@@ -186,7 +364,7 @@ impl NetworkFilterDirection {
 | 
			
		||||
                return Err(LibVirtStructError::ParseFilteringChain(format!(
 | 
			
		||||
                    "Unkown filter direction {s}!"
 | 
			
		||||
                ))
 | 
			
		||||
                .into())
 | 
			
		||||
                .into());
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
@@ -210,28 +388,81 @@ pub enum Layer4State {
 | 
			
		||||
    NONE,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
 | 
			
		||||
pub enum Layer4Type {
 | 
			
		||||
    TCP,
 | 
			
		||||
    UDP,
 | 
			
		||||
    SCTP,
 | 
			
		||||
    ICMP,
 | 
			
		||||
    TCPipv6,
 | 
			
		||||
    UDPipv6,
 | 
			
		||||
    SCTPipv6,
 | 
			
		||||
    ICMPipv6,
 | 
			
		||||
impl Layer4State {
 | 
			
		||||
    pub fn from_xml(xml: &str) -> anyhow::Result<Self> {
 | 
			
		||||
        Ok(match xml {
 | 
			
		||||
            "NEW" => Self::NEW,
 | 
			
		||||
            "ESTABLISHED" => Self::ESTABLISHED,
 | 
			
		||||
            "RELATED" => Self::RELATED,
 | 
			
		||||
            "INVALID" => Self::INVALID,
 | 
			
		||||
            "NONE" => Self::NONE,
 | 
			
		||||
            s => {
 | 
			
		||||
                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)]
 | 
			
		||||
pub struct NetworkFilterSelectorIP<IPv> {
 | 
			
		||||
pub struct NetworkFilterSelectorIP {
 | 
			
		||||
    srcmacaddr: Option<String>,
 | 
			
		||||
    srcmacmask: Option<String>,
 | 
			
		||||
    dstmacaddr: 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>,
 | 
			
		||||
    srcipmask: Option<u8>,
 | 
			
		||||
    dstipaddr: Option<IPv>,
 | 
			
		||||
    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>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -245,41 +476,18 @@ pub enum NetworkFilterSelector {
 | 
			
		||||
        dst_mac_mask: Option<String>,
 | 
			
		||||
        comment: Option<String>,
 | 
			
		||||
    },
 | 
			
		||||
    Arp {
 | 
			
		||||
        srcmacaddr: Option<String>,
 | 
			
		||||
        srcmacmask: Option<String>,
 | 
			
		||||
        dstmacaddr: Option<String>,
 | 
			
		||||
        dstmacmask: Option<String>,
 | 
			
		||||
        arpsrcipaddr: Option<IpAddr>,
 | 
			
		||||
        arpsrcipmask: Option<u8>,
 | 
			
		||||
        arpdstipaddr: Option<IpAddr>,
 | 
			
		||||
        arpdstipmask: Option<u8>,
 | 
			
		||||
        comment: Option<String>,
 | 
			
		||||
    },
 | 
			
		||||
    IPv4(NetworkFilterSelectorIP<Ipv4Addr>),
 | 
			
		||||
    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>,
 | 
			
		||||
    },
 | 
			
		||||
    Arp(NetworkSelectorARP),
 | 
			
		||||
    Rarp(NetworkSelectorARP),
 | 
			
		||||
    IPv4(NetworkFilterSelectorIP),
 | 
			
		||||
    IPv6(NetworkFilterSelectorIP),
 | 
			
		||||
    TCP(NetworkSelectorLayer4<Ipv4Addr>),
 | 
			
		||||
    UDP(NetworkSelectorLayer4<Ipv4Addr>),
 | 
			
		||||
    SCTP(NetworkSelectorLayer4<Ipv4Addr>),
 | 
			
		||||
    ICMP(NetworkSelectorLayer4<Ipv4Addr>),
 | 
			
		||||
    TCPipv6(NetworkSelectorLayer4<Ipv6Addr>),
 | 
			
		||||
    UDPipv6(NetworkSelectorLayer4<Ipv6Addr>),
 | 
			
		||||
    SCTPipv6(NetworkSelectorLayer4<Ipv6Addr>),
 | 
			
		||||
    ICMPipv6(NetworkSelectorLayer4<Ipv6Addr>),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user