215 lines
8.5 KiB
Diff
215 lines
8.5 KiB
Diff
From a85b3dddf82f9e71774229740fbae6ea843d86d6 Mon Sep 17 00:00:00 2001
|
|
From: Gris Ge <fge@redhat.com>
|
|
Date: Mon, 18 Jan 2021 15:55:43 +0800
|
|
Subject: [PATCH 1/2] ifaces: Don't validate undesired interface for overbook
|
|
|
|
There is no need to validate overbooked interface for undesired
|
|
controller interface.
|
|
|
|
Unit test case included.
|
|
|
|
Signed-off-by: Gris Ge <fge@redhat.com>
|
|
---
|
|
libnmstate/ifaces/ifaces.py | 2 ++
|
|
1 file changed, 2 insertions(+)
|
|
|
|
diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py
|
|
index 7723f43..ee75125 100644
|
|
--- a/libnmstate/ifaces/ifaces.py
|
|
+++ b/libnmstate/ifaces/ifaces.py
|
|
@@ -437,6 +437,8 @@ class Ifaces:
|
|
"""
|
|
slave_master_map = {}
|
|
for iface in self._ifaces.values():
|
|
+ if not (iface.is_changed or iface.is_desired) or not iface.is_up:
|
|
+ continue
|
|
for slave_name in iface.slaves:
|
|
cur_master = slave_master_map.get(slave_name)
|
|
if cur_master:
|
|
--
|
|
2.27.0
|
|
|
|
|
|
From 644d8e5f5072caaba7151e66f211eceb02ae79c3 Mon Sep 17 00:00:00 2001
|
|
From: Gris Ge <fge@redhat.com>
|
|
Date: Thu, 21 Jan 2021 20:43:34 +0800
|
|
Subject: [PATCH 2/2] nm vlan/vxlan: Use uuid for VLAN/VxLAN parent
|
|
|
|
When parent of VLAN/VxLAN is holding the same name of OVS bridge or OVS
|
|
port, NetworkManager will fail with error failed to find interface index
|
|
of that parent.
|
|
|
|
The root cause is NetworkManager try to use user space interface as
|
|
VLAN/VxLAN parent.
|
|
|
|
To workaround that, use profile UUID for `NM.SettingVlan.props.parent`
|
|
and `NM.SettingVxlan.props.parent`.
|
|
|
|
Integration test case included.
|
|
|
|
Signed-off-by: Gris Ge <fge@redhat.com>
|
|
---
|
|
libnmstate/nm/applier.py | 98 +++++++++++++++++++++++++++++++++++--
|
|
libnmstate/nm/connection.py | 7 +++
|
|
2 files changed, 100 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/libnmstate/nm/applier.py b/libnmstate/nm/applier.py
|
|
index 26a057f..8e38df5 100644
|
|
--- a/libnmstate/nm/applier.py
|
|
+++ b/libnmstate/nm/applier.py
|
|
@@ -66,8 +66,6 @@ MASTER_IFACE_TYPES = (
|
|
|
|
|
|
def apply_changes(context, net_state, save_to_disk):
|
|
- con_profiles = []
|
|
-
|
|
if (
|
|
not save_to_disk
|
|
and _has_ovs_interface_desired_or_changed(net_state)
|
|
@@ -87,6 +85,10 @@ def apply_changes(context, net_state, save_to_disk):
|
|
_create_proxy_ifaces_desired_state(ifaces_desired_state)
|
|
)
|
|
|
|
+ # A list of tuple holding both current ConnectionProfile and new/updated
|
|
+ # ConnectionProfile.
|
|
+ pending_con_profiles = []
|
|
+
|
|
for iface_desired_state in filter(
|
|
lambda s: s.get(Interface.STATE) != InterfaceState.ABSENT,
|
|
ifaces_desired_state,
|
|
@@ -131,7 +133,7 @@ def apply_changes(context, net_state, save_to_disk):
|
|
# anything besides state:up and not been marked as changed.
|
|
# We don't need to do this once we support querying on-disk
|
|
# configure
|
|
- con_profiles.append(cur_con_profile)
|
|
+ pending_con_profiles.append((cur_con_profile, None))
|
|
continue
|
|
new_con_profile = _build_connection_profile(
|
|
context,
|
|
@@ -143,12 +145,25 @@ def apply_changes(context, net_state, save_to_disk):
|
|
set_conn = new_con_profile.profile.get_setting_connection()
|
|
set_conn.props.interface_name = iface_desired_state[Interface.NAME]
|
|
if cur_con_profile and cur_con_profile.profile:
|
|
- cur_con_profile.update(new_con_profile, save_to_disk)
|
|
- con_profiles.append(new_con_profile)
|
|
+ pending_con_profiles.append((cur_con_profile, new_con_profile))
|
|
else:
|
|
# Missing connection, attempting to create a new one.
|
|
+ pending_con_profiles.append((None, new_con_profile))
|
|
+
|
|
+ pending_con_profiles = _use_uuid_for_parent(
|
|
+ context, pending_con_profiles, save_to_disk
|
|
+ )
|
|
+
|
|
+ con_profiles = []
|
|
+ for cur_con_profile, new_con_profile in pending_con_profiles:
|
|
+ if cur_con_profile and new_con_profile:
|
|
+ cur_con_profile.update(new_con_profile, save_to_disk)
|
|
+ con_profiles.append(new_con_profile)
|
|
+ elif cur_con_profile is None and new_con_profile:
|
|
new_con_profile.add(save_to_disk)
|
|
con_profiles.append(new_con_profile)
|
|
+ elif cur_con_profile:
|
|
+ con_profiles.append(cur_con_profile)
|
|
context.wait_all_finish()
|
|
|
|
_set_ifaces_admin_state(context, ifaces_desired_state, con_profiles)
|
|
@@ -655,3 +670,76 @@ def _mark_nm_external_subordinate_changed(context, net_state):
|
|
subordinate_iface = net_state.ifaces.get(subordinate)
|
|
if subordinate_iface:
|
|
subordinate_iface.mark_as_changed()
|
|
+
|
|
+
|
|
+def _use_uuid_for_parent(context, pending_con_profiles, save_to_disk):
|
|
+ """
|
|
+ When parent of VLAN/VxLAN is holding the same name with
|
|
+ OVS bridge or OVS port, we should use UUID instead of interface name
|
|
+ """
|
|
+ new_pending_con_profiles = []
|
|
+ kernel_iface_name_to_uuid = {}
|
|
+ for cur_nm_profile in context.client.get_connections():
|
|
+ connection_type = cur_nm_profile.get_connection_type()
|
|
+ if connection_type not in (
|
|
+ NM.SETTING_OVS_BRIDGE_SETTING_NAME,
|
|
+ NM.SETTING_OVS_PORT_SETTING_NAME,
|
|
+ ):
|
|
+ kernel_iface_name_to_uuid[
|
|
+ cur_nm_profile.get_interface_name()
|
|
+ ] = cur_nm_profile.get_uuid()
|
|
+ # Override existing kernel_iface_name_to_uuid with pending changes.
|
|
+ for cur_con_profile, new_con_profile in pending_con_profiles:
|
|
+ if new_con_profile and new_con_profile.profile:
|
|
+ uuid = new_con_profile.profile.get_uuid()
|
|
+ connection_type = new_con_profile.profile.get_connection_type()
|
|
+ iface_name = new_con_profile.profile.get_interface_name()
|
|
+ elif cur_con_profile and cur_con_profile.profile:
|
|
+ uuid = cur_con_profile.profile.get_uuid()
|
|
+ connection_type = cur_con_profile.profile.get_connection_type()
|
|
+ iface_name = cur_con_profile.profile.get_interface_name()
|
|
+ else:
|
|
+ continue
|
|
+
|
|
+ if connection_type not in (
|
|
+ NM.SETTING_OVS_BRIDGE_SETTING_NAME,
|
|
+ NM.SETTING_OVS_PORT_SETTING_NAME,
|
|
+ ):
|
|
+ kernel_iface_name_to_uuid[iface_name] = uuid
|
|
+
|
|
+ for cur_con_profile, new_con_profile in pending_con_profiles:
|
|
+ new_pending_con_profiles.append((cur_con_profile, new_con_profile))
|
|
+ if not new_con_profile:
|
|
+ continue
|
|
+ nm_profile = new_con_profile.profile
|
|
+ if not nm_profile:
|
|
+ continue
|
|
+ connection_type = nm_profile.get_connection_type()
|
|
+ nm_setting = None
|
|
+ if connection_type == NM.SETTING_VLAN_SETTING_NAME:
|
|
+ nm_setting = nm_profile.get_setting_vlan()
|
|
+ elif connection_type == NM.SETTING_VXLAN_SETTING_NAME:
|
|
+ nm_setting = nm_profile.get_setting_vxlan()
|
|
+ else:
|
|
+ continue
|
|
+ if not nm_setting:
|
|
+ continue
|
|
+ parent_iface_name = nm_setting.props.parent
|
|
+ parent_uuid = kernel_iface_name_to_uuid.get(parent_iface_name)
|
|
+ if parent_uuid:
|
|
+ updated_con_profile = connection.ConnectionProfile(context)
|
|
+ new_nm_settings = []
|
|
+ for cur_nm_setting in nm_profile.get_settings():
|
|
+ new_nm_setting = cur_nm_setting.duplicate()
|
|
+ if new_nm_setting.get_name() in (
|
|
+ NM.SETTING_VLAN_SETTING_NAME,
|
|
+ NM.SETTING_VXLAN_SETTING_NAME,
|
|
+ ):
|
|
+ new_nm_setting.props.parent = parent_uuid
|
|
+ new_nm_settings.append(new_nm_setting)
|
|
+ updated_con_profile.create(new_nm_settings)
|
|
+ new_pending_con_profiles.pop()
|
|
+ new_pending_con_profiles.append(
|
|
+ (cur_con_profile, updated_con_profile)
|
|
+ )
|
|
+ return new_pending_con_profiles
|
|
diff --git a/libnmstate/nm/connection.py b/libnmstate/nm/connection.py
|
|
index af7296f..5b9a3ae 100644
|
|
--- a/libnmstate/nm/connection.py
|
|
+++ b/libnmstate/nm/connection.py
|
|
@@ -63,6 +63,13 @@ class ConnectionProfile:
|
|
if self.con_id:
|
|
self.profile = self._ctx.client.get_connection_by_id(self.con_id)
|
|
|
|
+ def import_by_uuid(self, uuid):
|
|
+ for nm_profile in self._ctx.client.get_connections():
|
|
+ if nm_profile.get_uuid() == uuid:
|
|
+ self.profile = nm_profile
|
|
+ return
|
|
+ logging.debug(f"Failed to find {uuid} profile")
|
|
+
|
|
def update(self, con_profile, save_to_disk=True):
|
|
flags = NM.SettingsUpdate2Flags.BLOCK_AUTOCONNECT
|
|
if save_to_disk:
|
|
--
|
|
2.27.0
|
|
|