Add new attribute to 'all' rules

This commit is contained in:
2024-01-04 16:53:24 +01:00
parent 307e5d1b50
commit 8cd32d35e2
5 changed files with 291 additions and 98 deletions

View File

@ -9,13 +9,6 @@ pub struct NetworkFilterRefXML {
pub filter: String,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
#[serde(rename = "all")]
pub struct NetworkFilterRuleProtocolAllXML {
#[serde(rename = "@comment", skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
#[serde(rename = "mac")]
pub struct NetworkFilterRuleProtocolMac {
@ -50,7 +43,6 @@ pub struct NetworkFilterRuleProtocolArpXML {
pub arpdstipaddr: Option<String>,
#[serde(rename = "@arpdstipmask", skip_serializing_if = "Option::is_none")]
pub arpdstipmask: Option<u8>,
#[serde(rename = "@comment", skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
}
@ -114,7 +106,37 @@ pub struct NetworkFilterRuleProtocolLayer4<IPv> {
pub dstportend: Option<u16>,
#[serde(rename = "@state", skip_serializing_if = "Option::is_none")]
pub state: Option<String>,
#[serde(rename = "@comment", skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
#[serde(rename = "all")]
pub struct NetworkFilterRuleProtocolAllXML<IPv> {
#[serde(rename = "@srcmacaddr", skip_serializing_if = "Option::is_none")]
pub srcmacaddr: Option<String>,
#[serde(rename = "@srcipaddr", skip_serializing_if = "Option::is_none")]
pub srcipaddr: Option<IPv>,
#[serde(rename = "@srcipmask", skip_serializing_if = "Option::is_none")]
pub srcipmask: Option<u8>,
#[serde(rename = "@dstipaddr", skip_serializing_if = "Option::is_none")]
pub dstipaddr: Option<IPv>,
#[serde(rename = "@dstipmask", skip_serializing_if = "Option::is_none")]
pub dstipmask: Option<u8>,
/// Start of range of source IP address
#[serde(rename = "@srcipfrom", skip_serializing_if = "Option::is_none")]
pub srcipfrom: Option<IPv>,
/// End of range of source IP address
#[serde(rename = "@srcipto", skip_serializing_if = "Option::is_none")]
pub srcipto: Option<IPv>,
/// Start of range of destination IP address
#[serde(rename = "@dstipfrom", skip_serializing_if = "Option::is_none")]
pub dstipfrom: Option<IPv>,
/// End of range of destination IP address
#[serde(rename = "@dstipto", skip_serializing_if = "Option::is_none")]
pub dstipto: Option<IPv>,
#[serde(rename = "@state", skip_serializing_if = "Option::is_none")]
pub state: Option<String>,
#[serde(rename = "@comment", skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
}
@ -129,14 +151,6 @@ pub struct NetworkFilterRuleXML {
#[serde(rename = "@priority")]
pub priority: Option<i32>,
/// Match all protocols
#[serde(default, rename = "all", skip_serializing_if = "Vec::is_empty")]
pub all_selectors: Vec<NetworkFilterRuleProtocolAllXML>,
/// Match all ipv6 protocols
#[serde(default, rename = "all-ipv6", skip_serializing_if = "Vec::is_empty")]
pub all_ipv6_selectors: Vec<NetworkFilterRuleProtocolAllXML>,
/// Match mac protocol
#[serde(default, rename = "mac", skip_serializing_if = "Vec::is_empty")]
pub mac_selectors: Vec<NetworkFilterRuleProtocolMac>,
@ -173,6 +187,10 @@ pub struct NetworkFilterRuleXML {
#[serde(default, rename = "icmp", skip_serializing_if = "Vec::is_empty")]
pub icmp_selectors: Vec<NetworkFilterRuleProtocolLayer4<Ipv4Addr>>,
/// Match all protocols
#[serde(default, rename = "all", skip_serializing_if = "Vec::is_empty")]
pub all_selectors: Vec<NetworkFilterRuleProtocolAllXML<Ipv4Addr>>,
/// Match TCP IPv6 protocol
#[serde(default, rename = "tcp-ipv6", skip_serializing_if = "Vec::is_empty")]
pub tcp_ipv6_selectors: Vec<NetworkFilterRuleProtocolLayer4<Ipv6Addr>>,
@ -188,6 +206,10 @@ pub struct NetworkFilterRuleXML {
/// Match ICMP IPv6 protocol
#[serde(default, rename = "icmpv6", skip_serializing_if = "Vec::is_empty")]
pub imcp_ipv6_selectors: Vec<NetworkFilterRuleProtocolLayer4<Ipv6Addr>>,
/// Match all ipv6 protocols
#[serde(default, rename = "all-ipv6", skip_serializing_if = "Vec::is_empty")]
pub all_ipv6_selectors: Vec<NetworkFilterRuleProtocolAllXML<Ipv6Addr>>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]

View File

@ -308,11 +308,6 @@ impl Layer4State {
}
}
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct NetworkSelectorAll {
comment: Option<String>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct NetworkSelectorMac {
src_mac_addr: Option<NetworkFilterMacAddressOrVar>,
@ -371,10 +366,28 @@ pub struct NetworkFilterSelectorLayer4<IPv> {
comment: Option<String>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct NetworkSelectorAll<IPv> {
comment: Option<String>,
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>,
state: Option<Layer4State>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum NetworkFilterSelector {
All(NetworkSelectorAll),
Mac(NetworkSelectorMac),
Arp(NetworkSelectorARP),
Rarp(NetworkSelectorARP),
@ -384,11 +397,12 @@ pub enum NetworkFilterSelector {
UDP(NetworkFilterSelectorLayer4<Ipv4Addr>),
SCTP(NetworkFilterSelectorLayer4<Ipv4Addr>),
ICMP(NetworkFilterSelectorLayer4<Ipv4Addr>),
Allipv6(NetworkSelectorAll),
All(NetworkSelectorAll<Ipv4Addr>),
TCPipv6(NetworkFilterSelectorLayer4<Ipv6Addr>),
UDPipv6(NetworkFilterSelectorLayer4<Ipv6Addr>),
SCTPipv6(NetworkFilterSelectorLayer4<Ipv6Addr>),
ICMPipv6(NetworkFilterSelectorLayer4<Ipv6Addr>),
Allipv6(NetworkSelectorAll<Ipv6Addr>),
}
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
@ -416,12 +430,6 @@ pub struct NetworkFilter {
}
impl NetworkFilter {
fn lib2rest_process_all_rule(n: &NetworkFilterRuleProtocolAllXML) -> NetworkSelectorAll {
NetworkSelectorAll {
comment: n.comment.clone(),
}
}
fn lib2rest_process_mac_rule(n: &NetworkFilterRuleProtocolMac) -> NetworkFilterSelector {
NetworkFilterSelector::Mac(NetworkSelectorMac {
src_mac_addr: n.srcmacaddr.as_ref().map(|v| v.into()),
@ -484,28 +492,29 @@ impl NetworkFilter {
})
}
fn lib2rest_process_all_rule<IPv: Copy>(
n: &NetworkFilterRuleProtocolAllXML<IPv>,
) -> anyhow::Result<NetworkSelectorAll<IPv>> {
Ok(NetworkSelectorAll {
srcmacaddr: n.srcmacaddr.as_ref().map(|v| v.into()),
srcipaddr: n.srcipaddr,
srcipmask: n.srcipmask,
dstipaddr: n.dstipaddr,
dstipmask: n.dstipmask,
srcipfrom: n.srcipfrom,
srcipto: n.srcipto,
dstipfrom: n.dstipfrom,
dstipto: n.dstipto,
state: n.state.as_deref().map(Layer4State::from_xml).transpose()?,
comment: n.comment.clone(),
})
}
pub fn lib2rest(xml: NetworkFilterXML) -> anyhow::Result<Self> {
let mut rules = Vec::with_capacity(xml.rules.len());
for rule in &xml.rules {
let mut selectors = Vec::new();
// All selectors
selectors.append(
&mut rule
.all_selectors
.iter()
.map(|r| NetworkFilterSelector::All(Self::lib2rest_process_all_rule(r)))
.collect(),
);
selectors.append(
&mut rule
.all_ipv6_selectors
.iter()
.map(|r| NetworkFilterSelector::Allipv6(Self::lib2rest_process_all_rule(r)))
.collect(),
);
// Mac selectors
selectors.append(
&mut rule
@ -638,6 +647,31 @@ impl NetworkFilter {
.collect::<Result<Vec<_>, anyhow::Error>>()?,
);
// All selectors
selectors.append(
&mut rule
.all_selectors
.iter()
.map(|r| {
Ok(NetworkFilterSelector::All(Self::lib2rest_process_all_rule(
r,
)?))
})
.collect::<Result<Vec<_>, anyhow::Error>>()?,
);
selectors.append(
&mut rule
.all_ipv6_selectors
.iter()
.map(|r| {
Ok(NetworkFilterSelector::Allipv6(
Self::lib2rest_process_all_rule(r)?,
))
})
.collect::<Result<Vec<_>, anyhow::Error>>()?,
);
rules.push(NetworkFilterRule {
action: NetworkFilterAction::from_xml(&rule.action)?,
direction: NetworkFilterDirection::from_xml(&rule.direction)?,
@ -664,14 +698,6 @@ impl NetworkFilter {
})
}
fn rest2lib_process_all_selector(
selector: &NetworkSelectorAll,
) -> anyhow::Result<NetworkFilterRuleProtocolAllXML> {
Ok(NetworkFilterRuleProtocolAllXML {
comment: extract_nw_filter_comment(&selector.comment)?,
})
}
fn rest2lib_process_arp_selector(
selector: &NetworkSelectorARP,
) -> anyhow::Result<NetworkFilterRuleProtocolArpXML> {
@ -728,6 +754,26 @@ impl NetworkFilter {
})
}
fn rest2lib_process_all_selector<IPv: Copy>(
selector: &NetworkSelectorAll<IPv>,
) -> anyhow::Result<NetworkFilterRuleProtocolAllXML<IPv>> {
Ok(NetworkFilterRuleProtocolAllXML {
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,
state: selector.state.map(|s| s.to_xml()),
comment: extract_nw_filter_comment(&selector.comment)?,
})
}
fn rest2lib_process_rule(rule: &NetworkFilterRule) -> anyhow::Result<NetworkFilterRuleXML> {
let mut rule_xml = NetworkFilterRuleXML {
action: rule.action.to_xml(),
@ -738,18 +784,6 @@ impl NetworkFilter {
for sel in &rule.selectors {
match sel {
NetworkFilterSelector::All(all) => {
rule_xml
.all_selectors
.push(Self::rest2lib_process_all_selector(all)?);
}
NetworkFilterSelector::Allipv6(all) => {
rule_xml
.all_ipv6_selectors
.push(Self::rest2lib_process_all_selector(all)?);
}
NetworkFilterSelector::Mac(mac) => {
rule_xml.mac_selectors.push(NetworkFilterRuleProtocolMac {
srcmacaddr: extract_mac_address_or_var(&mac.src_mac_addr)?,
@ -765,6 +799,7 @@ impl NetworkFilter {
.arp_selectors
.push(Self::rest2lib_process_arp_selector(a)?);
}
NetworkFilterSelector::Rarp(a) => {
rule_xml
.rarp_selectors
@ -774,7 +809,6 @@ impl NetworkFilter {
NetworkFilterSelector::IPv4(ip) => rule_xml
.ipv4_selectors
.push(Self::rest2lib_process_ip_selector(ip)?),
NetworkFilterSelector::IPv6(ip) => rule_xml
.ipv6_selectors
.push(Self::rest2lib_process_ip_selector(ip)?),
@ -795,6 +829,12 @@ impl NetworkFilter {
.icmp_selectors
.push(Self::rest2lib_process_layer4_selector(icmp)?),
NetworkFilterSelector::All(all) => {
rule_xml
.all_selectors
.push(Self::rest2lib_process_all_selector(all)?);
}
NetworkFilterSelector::TCPipv6(tcpv6) => rule_xml
.tcp_ipv6_selectors
.push(Self::rest2lib_process_layer4_selector(tcpv6)?),
@ -810,6 +850,12 @@ impl NetworkFilter {
NetworkFilterSelector::ICMPipv6(icmpv6) => rule_xml
.imcp_ipv6_selectors
.push(Self::rest2lib_process_layer4_selector(icmpv6)?),
NetworkFilterSelector::Allipv6(all) => {
rule_xml
.all_ipv6_selectors
.push(Self::rest2lib_process_all_selector(all)?);
}
}
}