use super::super::nm_dbus::{NmApi, NmConnection, NmDevice};
use super::super::{
query_apply::profile::delete_profiles,
settings::{get_exist_profile, NM_SETTING_OVS_PORT_SETTING_NAME},
show::nm_conn_to_base_iface,
};
use crate::{
Interface, InterfaceType, MergedInterface, MergedInterfaces, NetworkState,
NmstateError,
};
pub(crate) fn delete_orphan_ovs_ports(
nm_api: &mut NmApi,
merged_ifaces: &MergedInterfaces,
exist_nm_conns: &[NmConnection],
nm_conns_to_activate: &[NmConnection],
) -> Result<(), NmstateError> {
let mut orphans: Vec<&str> = Vec::new();
for iface in merged_ifaces
.kernel_ifaces
.values()
.filter(|i| i.is_changed())
{
if iface
.for_apply
.as_ref()
.and_then(|i| i.base_iface().controller_type.as_ref())
!= Some(&InterfaceType::OvsBridge)
&& iface_was_ovs_sys_iface(iface)
{
if let Some(exist_profile) = get_exist_profile(
exist_nm_conns,
iface.merged.name(),
&iface.merged.iface_type(),
&Vec::new(),
) {
if exist_profile
.connection
.as_ref()
.and_then(|c| c.controller_type.as_ref())
== Some(&NM_SETTING_OVS_PORT_SETTING_NAME.to_string())
{
if let Some(parent) = exist_profile
.connection
.as_ref()
.and_then(|c| c.controller.as_ref())
{
if uuid::Uuid::parse_str(parent).is_ok() {
if nm_conns_to_activate
.iter()
.any(|nm_conn| nm_conn.uuid() == Some(parent))
{
continue;
}
log::info!(
"Deleting orphan OVS port connection {parent} \
as interface {}({}) detached from OVS bridge",
iface.merged.name(),
iface.merged.iface_type()
);
orphans.push(parent)
}
}
}
}
}
}
delete_profiles(nm_api, orphans.as_slice())
}
fn iface_was_ovs_sys_iface(iface: &MergedInterface) -> bool {
iface
.current
.as_ref()
.and_then(|i| i.base_iface().controller_type.as_ref())
== Some(&InterfaceType::OvsBridge)
}
pub(crate) fn merge_ovs_netdev_tun_iface(
net_state: &mut NetworkState,
nm_devs: &[NmDevice],
nm_conns: &[NmConnection],
) {
let tun_nm_devs: Vec<&NmDevice> = nm_devs
.iter()
.filter(|d| d.iface_type.as_str() == "tun")
.collect();
let tun_nm_conns: Vec<&NmConnection> = nm_conns
.iter()
.filter(|c| c.iface_type() == Some("tun"))
.collect();
for iface in net_state
.interfaces
.kernel_ifaces
.values_mut()
.filter(|i| i.iface_type() == InterfaceType::OvsInterface)
{
if let (Some(nm_dev), Some(nm_conn)) = (
tun_nm_devs
.as_slice()
.iter()
.find(|d| d.name.as_str() == iface.name()),
tun_nm_conns
.as_slice()
.iter()
.find(|c| c.iface_name() == Some(iface.name())),
) {
if let (Some(mut base_iface), Interface::OvsInterface(oiface)) = (
nm_conn_to_base_iface(Some(nm_dev), nm_conn, None, None),
iface,
) {
base_iface.iface_type = InterfaceType::OvsInterface;
if !base_iface.prop_list.contains(&"iface_type") {
base_iface.prop_list.push("iface_type");
}
oiface.base = base_iface;
}
}
}
}