use std::net::IpAddr;
use serde::{Deserialize, Serialize};
use crate::{BaseInterface, ErrorKind, InterfaceType, NmstateError};
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub struct IpTunnelInterface {
#[serde(flatten)]
pub base: BaseInterface,
#[serde(skip_serializing_if = "Option::is_none")]
pub ip_tunnel: Option<IpTunnelConfig>,
}
impl Default for IpTunnelInterface {
fn default() -> Self {
Self {
base: BaseInterface {
iface_type: InterfaceType::IpTunnel,
..Default::default()
},
ip_tunnel: None,
}
}
}
impl IpTunnelInterface {
pub fn new() -> Self {
Self::default()
}
pub(crate) fn sanitize(
&mut self,
is_desired: bool,
) -> Result<(), NmstateError> {
if is_desired
&& let Some(conf) = &mut self.ip_tunnel
&& let Some(flow_label) = conf.flow_label
&& flow_label > 0xFFFFF
{
return Err(NmstateError::new(
ErrorKind::InvalidArgument,
"Flow label must be less than 0xFFFFF".to_string(),
));
}
Ok(())
}
}
#[derive(
Serialize, Deserialize, Debug, Default, PartialEq, Eq, Clone, Copy,
)]
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub enum IpTunnelMode {
#[default]
Unknown,
Ipip,
Sit,
Ip6ip6,
Ipip6,
}
#[derive(
Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy,
)]
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub enum Ip6TunnelFlag {
IgnEncapLimit,
UseOrigTclass,
UseOrigFlowlabel,
Mip6Dev,
RcvDscpCopy,
UseOrigFwMark,
AllowLocalRemote,
CapXmit,
CapRcv,
CapPerPacket,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
#[derive(Default)]
pub struct IpTunnelConfig {
pub mode: Option<IpTunnelMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub base_iface: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub local: Option<IpAddr>,
#[serde(skip_serializing_if = "Option::is_none")]
pub remote: Option<IpAddr>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ttl: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tos: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
pub flow_label: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ip6tun_flags: Option<Vec<Ip6TunnelFlag>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pmtu_disc: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub encap_limit: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
pub fwmark: Option<u32>,
}