Add Layer4 selectors extraction
This commit is contained in:
parent
c6c1ce26d3
commit
388a1ed478
@ -227,7 +227,7 @@ pub struct NetworkFilterRuleProtocolLayer4<IPv> {
|
||||
pub comment: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Default)]
|
||||
#[serde(rename = "rule")]
|
||||
pub struct NetworkFilterRuleXML {
|
||||
#[serde(rename(serialize = "@action"))]
|
||||
@ -275,7 +275,7 @@ pub struct NetworkFilterRuleXML {
|
||||
|
||||
/// Match ICMP protocol
|
||||
#[serde(default, rename = "icmp", skip_serializing_if = "Vec::is_empty")]
|
||||
pub imcp_selectors: Vec<NetworkFilterRuleProtocolLayer4<Ipv4Addr>>,
|
||||
pub icmp_selectors: Vec<NetworkFilterRuleProtocolLayer4<Ipv4Addr>>,
|
||||
|
||||
/// Match TCP IPv6 protocol
|
||||
#[serde(default, rename = "tcp-ipv6", skip_serializing_if = "Vec::is_empty")]
|
||||
|
@ -96,14 +96,14 @@ fn extract_ip_or_var<const V: usize>(
|
||||
Ok(n.as_ref().map(|n| n.0.to_string()))
|
||||
}
|
||||
|
||||
fn extract_ip_mask<const V: usize>(n: &Option<u8>) -> anyhow::Result<Option<u8>> {
|
||||
fn extract_ip_mask<const V: usize>(n: Option<u8>) -> anyhow::Result<Option<u8>> {
|
||||
if let Some(mask) = n {
|
||||
if !net_utils::is_mask_valid(V, *mask) {
|
||||
return Err(NetworkFilterExtraction(format!("Invalid IPv{V} mask! {}", mask)).into());
|
||||
if !net_utils::is_mask_valid(V, mask) {
|
||||
return Err(NetworkFilterExtraction(format!("Invalid IPv{V} mask! {mask}")).into());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(*n)
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
fn extract_nw_filter_comment(n: &Option<String>) -> anyhow::Result<Option<String>> {
|
||||
@ -192,6 +192,211 @@ impl NetworkFilterChain {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Copy, Clone)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum NetworkFilterAction {
|
||||
/// matching the rule silently discards the packet with no further analysis
|
||||
Drop,
|
||||
/// matching the rule generates an ICMP reject message with no further analysis
|
||||
Reject,
|
||||
/// matching the rule accepts the packet with no further analysis
|
||||
Accept,
|
||||
/// matching the rule passes this filter, but returns control to the calling filter for further
|
||||
/// analysis
|
||||
Return,
|
||||
/// matching the rule goes on to the next rule for further analysis
|
||||
Continue,
|
||||
}
|
||||
|
||||
impl NetworkFilterAction {
|
||||
pub fn from_xml(xml: &str) -> anyhow::Result<Self> {
|
||||
Ok(match xml {
|
||||
"drop" => Self::Drop,
|
||||
"reject" => Self::Reject,
|
||||
"accept" => Self::Accept,
|
||||
"return" => Self::Return,
|
||||
"continue" => Self::Continue,
|
||||
s => {
|
||||
return Err(LibVirtStructError::ParseFilteringChain(format!(
|
||||
"Unkown filter action {s}!"
|
||||
))
|
||||
.into());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_xml(&self) -> String {
|
||||
match self {
|
||||
Self::Drop => "drop",
|
||||
Self::Reject => "reject",
|
||||
Self::Accept => "accept",
|
||||
Self::Return => "return",
|
||||
Self::Continue => "continue",
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum NetworkFilterDirection {
|
||||
In,
|
||||
Out,
|
||||
InOut,
|
||||
}
|
||||
|
||||
impl NetworkFilterDirection {
|
||||
pub fn from_xml(xml: &str) -> anyhow::Result<Self> {
|
||||
Ok(match xml {
|
||||
"in" => Self::In,
|
||||
"out" => Self::Out,
|
||||
"inout" => Self::InOut,
|
||||
s => {
|
||||
return Err(LibVirtStructError::ParseFilteringChain(format!(
|
||||
"Unkown filter direction {s}!"
|
||||
))
|
||||
.into());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_xml(&self) -> String {
|
||||
match self {
|
||||
NetworkFilterDirection::In => "in",
|
||||
NetworkFilterDirection::Out => "out",
|
||||
NetworkFilterDirection::InOut => "inout",
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Copy, Clone)]
|
||||
pub enum Layer4State {
|
||||
NEW,
|
||||
ESTABLISHED,
|
||||
RELATED,
|
||||
INVALID,
|
||||
NONE,
|
||||
}
|
||||
|
||||
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 NetworkSelectorMac {
|
||||
src_mac_addr: Option<NetworkFilterMacAddressOrVar>,
|
||||
src_mac_mask: Option<NetworkFilterMacAddressOrVar>,
|
||||
dst_mac_addr: Option<NetworkFilterMacAddressOrVar>,
|
||||
dst_mac_mask: Option<NetworkFilterMacAddressOrVar>,
|
||||
comment: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct NetworkSelectorARP {
|
||||
srcmacaddr: Option<NetworkFilterMacAddressOrVar>,
|
||||
srcmacmask: Option<NetworkFilterMacAddressOrVar>,
|
||||
dstmacaddr: Option<NetworkFilterMacAddressOrVar>,
|
||||
dstmacmask: Option<NetworkFilterMacAddressOrVar>,
|
||||
arpsrcipaddr: Option<NetworkFilterIPv4OrVar>,
|
||||
arpsrcipmask: Option<u8>,
|
||||
arpdstipaddr: Option<NetworkFilterIPv4OrVar>,
|
||||
arpdstipmask: Option<u8>,
|
||||
comment: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct NetworkFilterSelectorIP<const V: usize> {
|
||||
srcmacaddr: Option<NetworkFilterMacAddressOrVar>,
|
||||
srcmacmask: Option<NetworkFilterMacAddressOrVar>,
|
||||
dstmacaddr: Option<NetworkFilterMacAddressOrVar>,
|
||||
dstmacmask: Option<NetworkFilterMacAddressOrVar>,
|
||||
srcipaddr: Option<NetworkFilterIPOrVar<V>>,
|
||||
srcipmask: Option<u8>,
|
||||
dstipaddr: Option<NetworkFilterIPOrVar<V>>,
|
||||
dstipmask: Option<u8>,
|
||||
comment: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct NetworkFilterSelectorLayer4<IPv> {
|
||||
srcmacaddr: Option<NetworkFilterMacAddressOrVar>,
|
||||
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>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
#[serde(tag = "type", rename_all = "lowercase")]
|
||||
pub enum NetworkFilterSelector {
|
||||
All,
|
||||
Mac(NetworkSelectorMac),
|
||||
Arp(NetworkSelectorARP),
|
||||
Rarp(NetworkSelectorARP),
|
||||
IPv4(NetworkFilterSelectorIP<4>),
|
||||
IPv6(NetworkFilterSelectorIP<6>),
|
||||
TCP(NetworkFilterSelectorLayer4<Ipv4Addr>),
|
||||
UDP(NetworkFilterSelectorLayer4<Ipv4Addr>),
|
||||
SCTP(NetworkFilterSelectorLayer4<Ipv4Addr>),
|
||||
ICMP(NetworkFilterSelectorLayer4<Ipv4Addr>),
|
||||
TCPipv6(NetworkFilterSelectorLayer4<Ipv6Addr>),
|
||||
UDPipv6(NetworkFilterSelectorLayer4<Ipv6Addr>),
|
||||
SCTPipv6(NetworkFilterSelectorLayer4<Ipv6Addr>),
|
||||
ICMPipv6(NetworkFilterSelectorLayer4<Ipv6Addr>),
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct NetworkFilterRule {
|
||||
action: NetworkFilterAction,
|
||||
direction: NetworkFilterDirection,
|
||||
/// optional; the priority of the rule controls the order in which the rule will be instantiated
|
||||
/// relative to other rules
|
||||
///
|
||||
/// Valid values are in the range of -1000 to 1000.
|
||||
priority: Option<i32>,
|
||||
selectors: Vec<NetworkFilterSelector>,
|
||||
}
|
||||
|
||||
/// Network filter definition
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct NetworkFilter {
|
||||
@ -251,8 +456,8 @@ impl NetworkFilter {
|
||||
|
||||
fn lib2rest_process_layer4_rule<IPv: Copy>(
|
||||
n: &NetworkFilterRuleProtocolLayer4<IPv>,
|
||||
) -> anyhow::Result<NetworkSelectorLayer4<IPv>> {
|
||||
Ok(NetworkSelectorLayer4 {
|
||||
) -> anyhow::Result<NetworkFilterSelectorLayer4<IPv>> {
|
||||
Ok(NetworkFilterSelectorLayer4 {
|
||||
srcmacaddr: n.srcmacaddr.as_ref().map(|v| v.into()),
|
||||
srcipaddr: n.srcipaddr,
|
||||
srcipmask: n.srcipmask,
|
||||
@ -362,7 +567,7 @@ impl NetworkFilter {
|
||||
);
|
||||
selectors.append(
|
||||
&mut rule
|
||||
.imcp_selectors
|
||||
.icmp_selectors
|
||||
.iter()
|
||||
.map(|r| {
|
||||
Ok(NetworkFilterSelector::ICMP(
|
||||
@ -468,9 +673,33 @@ impl NetworkFilter {
|
||||
dstmacaddr: extract_mac_address_or_var(&selector.dstmacaddr)?,
|
||||
dstmacmask: extract_mac_address_or_var(&selector.dstmacmask)?,
|
||||
srcipaddr: extract_ip_or_var(&selector.srcipaddr)?,
|
||||
srcipmask: extract_ip_mask::<V>(&selector.srcipmask)?,
|
||||
srcipmask: extract_ip_mask::<V>(selector.srcipmask)?,
|
||||
dstipaddr: extract_ip_or_var(&selector.dstipaddr)?,
|
||||
dstipmask: extract_ip_mask::<V>(&selector.dstipmask)?,
|
||||
dstipmask: extract_ip_mask::<V>(selector.dstipmask)?,
|
||||
comment: extract_nw_filter_comment(&selector.comment)?,
|
||||
})
|
||||
}
|
||||
|
||||
fn rest2lib_process_layer4_selector<IPv: Copy>(
|
||||
selector: &NetworkFilterSelectorLayer4<IPv>,
|
||||
) -> anyhow::Result<NetworkFilterRuleProtocolLayer4<IPv>> {
|
||||
Ok(NetworkFilterRuleProtocolLayer4 {
|
||||
srcmacaddr: extract_mac_address_or_var(&selector.srcmacaddr)?,
|
||||
srcipaddr: selector.srcipaddr,
|
||||
// This IP mask is not checked
|
||||
srcipmask: selector.srcipmask,
|
||||
dstipaddr: selector.dstipaddr,
|
||||
// This IP mask is not checked
|
||||
dstipmask: selector.dstipmask,
|
||||
srcipfrom: selector.srcipfrom,
|
||||
srcipto: selector.srcipto,
|
||||
dstipfrom: selector.dstipfrom,
|
||||
dstipto: selector.dstipto,
|
||||
srcportstart: selector.srcportstart,
|
||||
srcportend: selector.srcportend,
|
||||
dstportstart: selector.dstportstart,
|
||||
dstportend: selector.dstportend,
|
||||
state: selector.state.map(|s| s.to_xml()),
|
||||
comment: extract_nw_filter_comment(&selector.comment)?,
|
||||
})
|
||||
}
|
||||
@ -480,20 +709,7 @@ impl NetworkFilter {
|
||||
action: rule.action.to_xml(),
|
||||
direction: rule.direction.to_xml(),
|
||||
priority: rule.priority,
|
||||
all_selectors: vec![],
|
||||
mac_selectors: vec![],
|
||||
arp_selectors: vec![],
|
||||
rarp_selectors: vec![],
|
||||
ipv4_selectors: vec![],
|
||||
ipv6_selectors: vec![],
|
||||
tcp_selectors: vec![],
|
||||
udp_selectors: vec![],
|
||||
sctp_selectors: vec![],
|
||||
imcp_selectors: vec![],
|
||||
tcp_ipv6_selectors: vec![],
|
||||
udp_ipv6_selectors: vec![],
|
||||
sctp_ipv6_selectors: vec![],
|
||||
imcp_ipv6_selectors: vec![],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
for sel in &rule.selectors {
|
||||
@ -531,14 +747,37 @@ impl NetworkFilter {
|
||||
.ipv6_selectors
|
||||
.push(Self::rest2lib_process_ip_selector(ip)?),
|
||||
|
||||
NetworkFilterSelector::TCP(_) => todo!(),
|
||||
NetworkFilterSelector::UDP(_) => todo!(),
|
||||
NetworkFilterSelector::SCTP(_) => todo!(),
|
||||
NetworkFilterSelector::ICMP(_) => todo!(),
|
||||
NetworkFilterSelector::TCPipv6(_) => todo!(),
|
||||
NetworkFilterSelector::UDPipv6(_) => todo!(),
|
||||
NetworkFilterSelector::SCTPipv6(_) => todo!(),
|
||||
NetworkFilterSelector::ICMPipv6(_) => todo!(),
|
||||
NetworkFilterSelector::TCP(tcp) => rule_xml
|
||||
.tcp_selectors
|
||||
.push(Self::rest2lib_process_layer4_selector(tcp)?),
|
||||
|
||||
NetworkFilterSelector::UDP(udp) => rule_xml
|
||||
.udp_selectors
|
||||
.push(Self::rest2lib_process_layer4_selector(udp)?),
|
||||
|
||||
NetworkFilterSelector::SCTP(sctp) => rule_xml
|
||||
.sctp_selectors
|
||||
.push(Self::rest2lib_process_layer4_selector(sctp)?),
|
||||
|
||||
NetworkFilterSelector::ICMP(icmp) => rule_xml
|
||||
.icmp_selectors
|
||||
.push(Self::rest2lib_process_layer4_selector(icmp)?),
|
||||
|
||||
NetworkFilterSelector::TCPipv6(tcpv6) => rule_xml
|
||||
.tcp_ipv6_selectors
|
||||
.push(Self::rest2lib_process_layer4_selector(tcpv6)?),
|
||||
|
||||
NetworkFilterSelector::UDPipv6(udpv6) => rule_xml
|
||||
.udp_ipv6_selectors
|
||||
.push(Self::rest2lib_process_layer4_selector(udpv6)?),
|
||||
|
||||
NetworkFilterSelector::SCTPipv6(sctpv6) => rule_xml
|
||||
.sctp_ipv6_selectors
|
||||
.push(Self::rest2lib_process_layer4_selector(sctpv6)?),
|
||||
|
||||
NetworkFilterSelector::ICMPipv6(icmpv6) => rule_xml
|
||||
.imcp_ipv6_selectors
|
||||
.push(Self::rest2lib_process_layer4_selector(icmpv6)?),
|
||||
}
|
||||
}
|
||||
|
||||
@ -591,211 +830,6 @@ impl NetworkFilter {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Copy, Clone)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum NetworkFilterAction {
|
||||
/// matching the rule silently discards the packet with no further analysis
|
||||
Drop,
|
||||
/// matching the rule generates an ICMP reject message with no further analysis
|
||||
Reject,
|
||||
/// matching the rule accepts the packet with no further analysis
|
||||
Accept,
|
||||
/// matching the rule passes this filter, but returns control to the calling filter for further
|
||||
/// analysis
|
||||
Return,
|
||||
/// matching the rule goes on to the next rule for further analysis
|
||||
Continue,
|
||||
}
|
||||
|
||||
impl NetworkFilterAction {
|
||||
pub fn from_xml(xml: &str) -> anyhow::Result<Self> {
|
||||
Ok(match xml {
|
||||
"drop" => Self::Drop,
|
||||
"reject" => Self::Reject,
|
||||
"accept" => Self::Accept,
|
||||
"return" => Self::Return,
|
||||
"continue" => Self::Continue,
|
||||
s => {
|
||||
return Err(LibVirtStructError::ParseFilteringChain(format!(
|
||||
"Unkown filter action {s}!"
|
||||
))
|
||||
.into());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_xml(&self) -> String {
|
||||
match self {
|
||||
Self::Drop => "drop",
|
||||
Self::Reject => "reject",
|
||||
Self::Accept => "accept",
|
||||
Self::Return => "return",
|
||||
Self::Continue => "continue",
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum NetworkFilterDirection {
|
||||
In,
|
||||
Out,
|
||||
InOut,
|
||||
}
|
||||
|
||||
impl NetworkFilterDirection {
|
||||
pub fn from_xml(xml: &str) -> anyhow::Result<Self> {
|
||||
Ok(match xml {
|
||||
"in" => Self::In,
|
||||
"out" => Self::Out,
|
||||
"inout" => Self::InOut,
|
||||
s => {
|
||||
return Err(LibVirtStructError::ParseFilteringChain(format!(
|
||||
"Unkown filter direction {s}!"
|
||||
))
|
||||
.into());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_xml(&self) -> String {
|
||||
match self {
|
||||
NetworkFilterDirection::In => "in",
|
||||
NetworkFilterDirection::Out => "out",
|
||||
NetworkFilterDirection::InOut => "inout",
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub enum Layer4State {
|
||||
NEW,
|
||||
ESTABLISHED,
|
||||
RELATED,
|
||||
INVALID,
|
||||
NONE,
|
||||
}
|
||||
|
||||
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 NetworkSelectorMac {
|
||||
src_mac_addr: Option<NetworkFilterMacAddressOrVar>,
|
||||
src_mac_mask: Option<NetworkFilterMacAddressOrVar>,
|
||||
dst_mac_addr: Option<NetworkFilterMacAddressOrVar>,
|
||||
dst_mac_mask: Option<NetworkFilterMacAddressOrVar>,
|
||||
comment: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct NetworkSelectorARP {
|
||||
srcmacaddr: Option<NetworkFilterMacAddressOrVar>,
|
||||
srcmacmask: Option<NetworkFilterMacAddressOrVar>,
|
||||
dstmacaddr: Option<NetworkFilterMacAddressOrVar>,
|
||||
dstmacmask: Option<NetworkFilterMacAddressOrVar>,
|
||||
arpsrcipaddr: Option<NetworkFilterIPv4OrVar>,
|
||||
arpsrcipmask: Option<u8>,
|
||||
arpdstipaddr: Option<NetworkFilterIPv4OrVar>,
|
||||
arpdstipmask: Option<u8>,
|
||||
comment: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct NetworkFilterSelectorIP<const V: usize> {
|
||||
srcmacaddr: Option<NetworkFilterMacAddressOrVar>,
|
||||
srcmacmask: Option<NetworkFilterMacAddressOrVar>,
|
||||
dstmacaddr: Option<NetworkFilterMacAddressOrVar>,
|
||||
dstmacmask: Option<NetworkFilterMacAddressOrVar>,
|
||||
srcipaddr: Option<NetworkFilterIPOrVar<V>>,
|
||||
srcipmask: Option<u8>,
|
||||
dstipaddr: Option<NetworkFilterIPOrVar<V>>,
|
||||
dstipmask: Option<u8>,
|
||||
comment: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct NetworkSelectorLayer4<IPv> {
|
||||
srcmacaddr: Option<NetworkFilterMacAddressOrVar>,
|
||||
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>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
#[serde(tag = "type", rename_all = "lowercase")]
|
||||
pub enum NetworkFilterSelector {
|
||||
All,
|
||||
Mac(NetworkSelectorMac),
|
||||
Arp(NetworkSelectorARP),
|
||||
Rarp(NetworkSelectorARP),
|
||||
IPv4(NetworkFilterSelectorIP<4>),
|
||||
IPv6(NetworkFilterSelectorIP<6>),
|
||||
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)]
|
||||
pub struct NetworkFilterRule {
|
||||
action: NetworkFilterAction,
|
||||
direction: NetworkFilterDirection,
|
||||
/// optional; the priority of the rule controls the order in which the rule will be instantiated
|
||||
/// relative to other rules
|
||||
///
|
||||
/// Valid values are in the range of -1000 to 1000.
|
||||
priority: Option<i32>,
|
||||
selectors: Vec<NetworkFilterSelector>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::libvirt_rest_structures::nw_filter::is_var_def;
|
||||
|
Loading…
Reference in New Issue
Block a user