use crate::{
ErrorKind, Interface, InterfaceType, LinuxBridgeInterface, NmstateError,
state::get_json_value_difference,
};
impl Interface {
pub(crate) fn sanitize_current_for_verify(&mut self) {
self.base_iface_mut().sanitize_current_for_verify();
if let Interface::LinuxBridge(iface) = self {
iface.sanitize_current_for_verify()
}
if let Interface::OvsBridge(iface) = self {
iface.sanitize_current_for_verify()
}
if let Interface::IpTunnel(iface) = self {
iface.sanitize_current_for_verify();
}
}
pub(crate) fn sanitize_desired_for_verify(&mut self) {
self.base_iface_mut().sanitize_desired_for_verify();
if let Interface::Ethernet(iface) = self {
iface.sanitize_desired_for_verify();
} else if let Interface::Hsr(iface) = self {
iface.sanitize_desired_for_verify();
} else if let Interface::IpTunnel(iface) = self {
iface.sanitize_desired_for_verify();
}
}
pub(crate) fn verify(
&mut self,
current: &Self,
) -> Result<(), NmstateError> {
let mut current = current.clone();
self.process_allow_extra_address(&mut current);
self.alt_name_pre_verify(&mut current);
let self_value = serde_json::to_value(self.clone())?;
let current_value = serde_json::to_value(current.clone())?;
if let Some((reference, desire, current)) = get_json_value_difference(
format!("{}.interface", self.name()),
&self_value,
¤t_value,
) {
if let (
serde_json::Value::Number(des),
serde_json::Value::Number(cur),
) = (desire, current)
&& desire.as_u64().unwrap_or(0) as i128
- cur.as_u64().unwrap_or(0) as i128
== 1
&& LinuxBridgeInterface::is_interger_rounded_up(&reference)
{
let e = NmstateError::new(
ErrorKind::KernelIntegerRoundedError,
format!(
"Linux kernel configured with 250 HZ will round \
up/down the integer in linux bridge {} option '{}' \
from {:?} to {:?}.",
self.name(),
reference,
des,
cur
),
);
log::error!("{e}");
return Err(e);
}
Err(NmstateError::new(
ErrorKind::VerificationError,
format!(
"Verification failure: {reference} desire '{desire}', \
current '{current}'"
),
))
} else {
Ok(())
}
}
pub fn update(&mut self, other: &Interface) {
self.base_iface_mut().update(other.base_iface());
if let Self::Unknown(_) = other {
return;
}
match self {
Self::LinuxBridge(iface) => {
if let Self::LinuxBridge(other_iface) = other {
iface.update_bridge(other_iface);
} else {
log::warn!(
"Don't know how to update iface {iface:?} with \
{other:?}"
);
}
}
Self::Bond(iface) => {
if let Self::Bond(other_iface) = other {
iface.update_bond(other_iface);
} else {
log::warn!(
"Don't know how to update iface {iface:?} with \
{other:?}"
);
}
}
Self::Ethernet(iface) => {
if let Self::Ethernet(other_iface) = other {
iface.update_ethernet(other_iface);
iface.update_veth(other_iface);
} else {
log::warn!(
"Don't know how to update iface {iface:?} with \
{other:?}"
);
}
}
Self::Vlan(iface) => {
if let Self::Vlan(other_iface) = other {
iface.update_vlan(other_iface);
} else {
log::warn!(
"Don't know how to update iface {iface:?} with \
{other:?}"
);
}
}
Self::Vxlan(iface) => {
if let Self::Vxlan(other_iface) = other {
iface.update_vxlan(other_iface);
} else {
log::warn!(
"Don't know how to update iface {iface:?} with \
{other:?}"
);
}
}
Self::OvsBridge(iface) => {
if let Self::OvsBridge(other_iface) = other {
iface.update_ovs_bridge(other_iface);
} else {
log::warn!(
"Don't know how to update iface {iface:?} with \
{other:?}"
);
}
}
Self::MacVlan(iface) => {
if let Self::MacVlan(other_iface) = other {
iface.update_mac_vlan(other_iface);
} else {
log::warn!(
"Don't know how to update iface {iface:?} with \
{other:?}"
);
}
}
Self::MacVtap(iface) => {
if let Self::MacVtap(other_iface) = other {
iface.update_mac_vtap(other_iface);
} else {
log::warn!(
"Don't know how to update iface {iface:?} with \
{other:?}"
);
}
}
Self::Vrf(iface) => {
if let Self::Vrf(other_iface) = other {
iface.update_vrf(other_iface);
} else {
log::warn!(
"Don't know how to update iface {iface:?} with \
{other:?}"
);
}
}
Self::InfiniBand(iface) => {
if let Self::InfiniBand(other_iface) = other {
iface.update_ib(other_iface);
} else {
log::warn!(
"Don't know how to update iface {iface:?} with \
{other:?}"
);
}
}
Self::OvsInterface(iface) => {
if let Self::OvsInterface(other_iface) = other {
iface.update_ovs_iface(other_iface);
} else {
log::warn!(
"Don't know how to update iface {iface:?} with \
{other:?}"
);
}
}
Self::MacSec(iface) => {
if let Self::MacSec(other_iface) = other {
iface.update_macsec(other_iface);
} else {
log::warn!(
"Don't know how to update iface {iface:?} with \
{other:?}"
);
}
}
Self::Hsr(iface) => {
if let Self::Hsr(other_iface) = other {
iface.update_hsr(other_iface);
} else {
log::warn!(
"Don't know how to update iface {iface:?} with \
{other:?}"
);
}
}
Self::Ipsec(iface) => {
if let Self::Ipsec(other_iface) = other {
iface.update_ipsec(other_iface);
} else {
log::warn!(
"Don't know how to update iface {iface:?} with \
{other:?}"
);
}
}
Self::IpVlan(iface) => {
if let Self::IpVlan(other_iface) = other {
iface.update_ipvlan(other_iface);
} else {
log::warn!(
"Don't know how to update iface {iface:?} with \
{other:?}"
);
}
}
_ => (),
}
}
pub(crate) fn include_diff_context(
&mut self,
desired: &Self,
current: &Self,
) {
self.base_iface_mut()
.include_diff_context(desired.base_iface(), current.base_iface());
if let (
Interface::Vlan(vlan_iface),
Interface::Vlan(des_iface),
Interface::Vlan(cur_iface),
) = (self, desired, current)
{
vlan_iface.include_diff_context(des_iface, cur_iface);
}
}
}
impl InterfaceType {
pub(crate) const SUPPORTED_LIST: [InterfaceType; 20] = [
InterfaceType::Bond,
InterfaceType::LinuxBridge,
InterfaceType::Dummy,
InterfaceType::Ethernet,
InterfaceType::Veth,
InterfaceType::MacVtap,
InterfaceType::MacVlan,
InterfaceType::OvsBridge,
InterfaceType::OvsInterface,
InterfaceType::Vlan,
InterfaceType::Vxlan,
InterfaceType::InfiniBand,
InterfaceType::Loopback,
InterfaceType::MacSec,
InterfaceType::Vrf,
InterfaceType::Hsr,
InterfaceType::Ipsec,
InterfaceType::IpTunnel,
InterfaceType::Xfrm,
InterfaceType::IpVlan,
];
}