import NetworkManager-1.44.0-5.el9_3

i9c changed/i9c/NetworkManager-1.44.0-5.el9_3
MSVSphere Packaging Team 10 months ago
parent 9e619dc366
commit 3ad63e35f8

@ -0,0 +1,270 @@
From 8f8845484ee74b1934cbd5f0cca997ba0504d543 Mon Sep 17 00:00:00 2001
From: Gris Ge <fge@redhat.com>
Date: Thu, 8 Feb 2024 23:36:34 +0800
Subject: [PATCH] bridge: skip VLAN filtering resetting in reapply if no vlan
change changed
When doing reapply on linux bridge interface, NetworkManager will reset
the VLAN filtering and default PVID which cause PVID been readded to all
bridge ports regardless they are managed by NetworkManager.
This is because Linux kernel will re-add PVID to bridge port upon the
changes of bridge default-pvid value.
To fix the issue, this patch introduce netlink parsing code for
`vlan_filtering` and `default_pvid` of NMPlatformLnkBridge, and use that
to compare desired VLAN filtering settings, skip the reset of VLAN
filter if `default_pvid` and `vlan_filtering` are unchanged.
Signed-off-by: Gris Ge <fge@redhat.com>
(cherry picked from commit 02c34d538c6a2b22bd09318496ba104eb43246b4)
(cherry picked from commit f990f9b4e4ffb5195fc89c4a8c6f251c0e01b501)
(cherry picked from commit c448e225198f7f8851fc01a8394529e7cbe25d4d)
---
src/core/devices/nm-device-bridge.c | 79 +++++++++++++++++---------
src/core/platform/tests/test-link.c | 2 +
src/libnm-platform/nm-linux-platform.c | 6 ++
src/libnm-platform/nm-platform.c | 13 ++++-
src/libnm-platform/nm-platform.h | 2 +
5 files changed, 72 insertions(+), 30 deletions(-)
diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c
index 9a45dbf3fc..73effc50b4 100644
--- a/src/core/devices/nm-device-bridge.c
+++ b/src/core/devices/nm-device-bridge.c
@@ -712,7 +712,27 @@ master_update_slave_connection(NMDevice *device,
}
static gboolean
-bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge)
+is_bridge_pvid_changed(NMDevice *device, NMSettingBridge *s_bridge)
+{
+ int ifindex = nm_device_get_ifindex(device);
+ const NMPlatformLnkBridge *nmp_link_br;
+ NMPlatform *platform = nm_device_get_platform(device);
+ bool desired_vlan_filtering = nm_setting_bridge_get_vlan_filtering(s_bridge);
+ guint16 desired_pvid = nm_setting_bridge_get_vlan_default_pvid(s_bridge);
+
+ nm_platform_link_refresh(platform, ifindex);
+ nmp_link_br = nm_platform_link_get_lnk_bridge(platform, ifindex, NULL);
+
+ if (nmp_link_br) {
+ return desired_vlan_filtering != nmp_link_br->vlan_filtering
+ || desired_pvid != nmp_link_br->default_pvid;
+ } else {
+ return TRUE;
+ }
+}
+
+static gboolean
+bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge, gboolean is_reapply)
{
NMDeviceBridge *self = NM_DEVICE_BRIDGE(device);
gconstpointer hwaddr;
@@ -753,31 +773,37 @@ bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge)
self->vlan_configured = TRUE;
- /* Filtering must be disabled to change the default PVID.
- * Clear the default PVID so that we later can force the re-creation of
- * default PVID VLANs by writing the option again. */
-
- nm_platform_link_set_bridge_info(
- plat,
- ifindex,
- &((NMPlatformLinkSetBridgeInfoData){.vlan_filtering_has = TRUE,
- .vlan_filtering_val = FALSE,
- .vlan_default_pvid_has = TRUE,
- .vlan_default_pvid_val = 0}));
+ if (!is_reapply || is_bridge_pvid_changed(device, s_bridge)) {
+ /* Filtering must be disabled to change the default PVID.
+ * Clear the default PVID so that we later can force the re-creation of
+ * default PVID VLANs by writing the option again. */
- /* Clear all existing VLANs */
- if (!nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, NULL))
- return FALSE;
+ if (is_reapply) {
+ _LOGD(LOGD_BRIDGE, "default_pvid is changed, resetting bridge VLAN filtering");
+ }
- /* Now set the default PVID. After this point the kernel creates
- * a PVID VLAN on each port, including the bridge itself. */
- pvid = nm_setting_bridge_get_vlan_default_pvid(s_bridge);
- if (pvid) {
nm_platform_link_set_bridge_info(
plat,
ifindex,
- &((NMPlatformLinkSetBridgeInfoData){.vlan_default_pvid_has = TRUE,
- .vlan_default_pvid_val = pvid}));
+ &((NMPlatformLinkSetBridgeInfoData){.vlan_filtering_has = TRUE,
+ .vlan_filtering_val = FALSE,
+ .vlan_default_pvid_has = TRUE,
+ .vlan_default_pvid_val = 0}));
+
+ /* Clear all existing VLANs */
+ if (!nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, NULL))
+ return FALSE;
+
+ /* Now set the default PVID. After this point the kernel creates
+ * a PVID VLAN on each port, including the bridge itself. */
+ pvid = nm_setting_bridge_get_vlan_default_pvid(s_bridge);
+ if (pvid) {
+ nm_platform_link_set_bridge_info(
+ plat,
+ ifindex,
+ &((NMPlatformLinkSetBridgeInfoData){.vlan_default_pvid_has = TRUE,
+ .vlan_default_pvid_val = pvid}));
+ }
}
/* Create VLANs only after setting the default PVID, so that
@@ -836,7 +862,7 @@ _platform_lnk_bridge_init_from_setting(NMSettingBridge *s_bridge, NMPlatformLnkB
}
static gboolean
-link_config(NMDevice *device, NMConnection *connection)
+link_config(NMDevice *device, NMConnection *connection, gboolean is_reapply)
{
int ifindex = nm_device_get_ifindex(device);
NMSettingBridge *s_bridge;
@@ -850,7 +876,7 @@ link_config(NMDevice *device, NMConnection *connection)
if (nm_platform_link_bridge_change(nm_device_get_platform(device), ifindex, &props) < 0)
return FALSE;
- return bridge_set_vlan_options(device, s_bridge);
+ return bridge_set_vlan_options(device, s_bridge, is_reapply);
}
static NMActStageReturn
@@ -861,7 +887,7 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
connection = nm_device_get_applied_connection(device);
g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE);
- if (!link_config(device, connection)) {
+ if (!link_config(device, connection, FALSE)) {
NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
return NM_ACT_STAGE_RETURN_FAILURE;
}
@@ -1003,7 +1029,7 @@ attach_port(NMDevice *device,
s_port = nm_connection_get_setting_bridge_port(connection);
if (!nm_device_sys_iface_state_is_external(device))
- bridge_set_vlan_options(device, s_bridge);
+ bridge_set_vlan_options(device, s_bridge, FALSE);
if (nm_setting_bridge_get_vlan_filtering(s_bridge)) {
gs_free const NMPlatformBridgeVlan **plat_vlans = NULL;
@@ -1218,8 +1244,7 @@ reapply_connection(NMDevice *device, NMConnection *con_old, NMConnection *con_ne
/* Make sure bridge_set_vlan_options() called by link_config()
* sets vlan_filtering and default_pvid anew. */
self->vlan_configured = FALSE;
-
- link_config(device, con_new);
+ link_config(device, con_new, TRUE);
}
/*****************************************************************************/
diff --git a/src/core/platform/tests/test-link.c b/src/core/platform/tests/test-link.c
index 8a54ac4853..fdece007bc 100644
--- a/src/core/platform/tests/test-link.c
+++ b/src/core/platform/tests/test-link.c
@@ -1403,6 +1403,8 @@ test_software_detect(gconstpointer user_data)
lnk_bridge.mcast_query_interval = 12000;
lnk_bridge.mcast_query_response_interval = 5200;
lnk_bridge.mcast_startup_query_interval = 3000;
+ lnk_bridge.vlan_filtering = FALSE;
+ lnk_bridge.default_pvid = 1;
if (!nmtstp_link_bridge_add(NULL, ext, DEVICE_NAME, &lnk_bridge))
g_error("Failed adding Bridge interface");
diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c
index 99eab9c784..9b4ac14024 100644
--- a/src/libnm-platform/nm-linux-platform.c
+++ b/src/libnm-platform/nm-linux-platform.c
@@ -1515,6 +1515,8 @@ _parse_lnk_bridge(const char *kind, struct nlattr *info_data)
[IFLA_BR_MCAST_QUERY_INTVL] = {.type = NLA_U64},
[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL] = {.type = NLA_U64},
[IFLA_BR_MCAST_STARTUP_QUERY_INTVL] = {.type = NLA_U64},
+ [IFLA_BR_VLAN_FILTERING] = {.type = NLA_U8},
+ [IFLA_BR_VLAN_DEFAULT_PVID] = {.type = NLA_U16},
};
NMPlatformLnkBridge *props;
struct nlattr *tb[G_N_ELEMENTS(policy)];
@@ -1585,6 +1587,10 @@ _parse_lnk_bridge(const char *kind, struct nlattr *info_data)
props->mcast_query_response_interval = nla_get_u64(tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL]);
if (tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL])
props->mcast_startup_query_interval = nla_get_u64(tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]);
+ if (tb[IFLA_BR_VLAN_FILTERING])
+ props->vlan_filtering = !!nla_get_u8(tb[IFLA_BR_VLAN_FILTERING]);
+ if (tb[IFLA_BR_VLAN_DEFAULT_PVID])
+ props->default_pvid = nla_get_u16(tb[IFLA_BR_VLAN_DEFAULT_PVID]);
return obj;
}
diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
index 041354cf44..3b61375bad 100644
--- a/src/libnm-platform/nm-platform.c
+++ b/src/libnm-platform/nm-platform.c
@@ -6086,7 +6086,8 @@ nm_platform_lnk_bridge_to_string(const NMPlatformLnkBridge *lnk, char *buf, gsiz
" mcast_querier_interval %" G_GUINT64_FORMAT
" mcast_query_interval %" G_GUINT64_FORMAT
" mcast_query_response_interval %" G_GUINT64_FORMAT
- " mcast_startup_query_interval %" G_GUINT64_FORMAT "",
+ " mcast_startup_query_interval %" G_GUINT64_FORMAT " vlan_filtering %d"
+ " default_pvid %" G_GUINT16_FORMAT "",
lnk->forward_delay,
lnk->hello_time,
lnk->max_age,
@@ -6109,7 +6110,9 @@ nm_platform_lnk_bridge_to_string(const NMPlatformLnkBridge *lnk, char *buf, gsiz
lnk->mcast_querier_interval,
lnk->mcast_query_interval,
lnk->mcast_query_response_interval,
- lnk->mcast_startup_query_interval);
+ lnk->mcast_startup_query_interval,
+ lnk->vlan_filtering,
+ lnk->default_pvid);
return buf;
}
@@ -7978,12 +7981,14 @@ nm_platform_lnk_bridge_hash_update(const NMPlatformLnkBridge *obj, NMHashState *
obj->mcast_router,
obj->mcast_query_response_interval,
obj->mcast_startup_query_interval,
+ obj->default_pvid,
NM_HASH_COMBINE_BOOLS(guint8,
obj->stp_state,
obj->mcast_querier,
obj->mcast_query_use_ifaddr,
obj->mcast_snooping,
- obj->vlan_stats_enabled));
+ obj->vlan_stats_enabled,
+ obj->vlan_filtering));
}
void
@@ -8124,6 +8129,8 @@ nm_platform_lnk_bridge_cmp(const NMPlatformLnkBridge *a, const NMPlatformLnkBrid
NM_CMP_FIELD(a, b, mcast_query_interval);
NM_CMP_FIELD(a, b, mcast_query_response_interval);
NM_CMP_FIELD(a, b, mcast_startup_query_interval);
+ NM_CMP_FIELD_BOOL(a, b, vlan_filtering);
+ NM_CMP_FIELD(a, b, default_pvid);
return 0;
}
diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h
index aeea5c42db..a4410b0a7c 100644
--- a/src/libnm-platform/nm-platform.h
+++ b/src/libnm-platform/nm-platform.h
@@ -765,6 +765,8 @@ typedef struct {
bool mcast_snooping : 1;
bool stp_state : 1;
bool vlan_stats_enabled : 1;
+ bool vlan_filtering;
+ guint16 default_pvid;
} _nm_alignas(NMPlatformObject) NMPlatformLnkBridge;
extern const NMPlatformLnkBridge nm_platform_lnk_bridge_default;
--
2.43.0

@ -6,7 +6,7 @@
%global epoch_version 1 %global epoch_version 1
%global real_version 1.44.0 %global real_version 1.44.0
%global rpm_version %{real_version} %global rpm_version %{real_version}
%global release_version 4 %global release_version 5
%global snapshot %{nil} %global snapshot %{nil}
%global git_sha %{nil} %global git_sha %{nil}
%global bcond_default_debug 0 %global bcond_default_debug 0
@ -205,6 +205,7 @@ Source7: readme-ifcfg-rh.txt
Patch1001: 1001-nm-manager-ensure-device-is-exported-on-D-Bus-in-aut-rhbz2210271.patch Patch1001: 1001-nm-manager-ensure-device-is-exported-on-D-Bus-in-aut-rhbz2210271.patch
Patch1002: 1002-checkpoint-Fix-segfault-crash-when-rollback-rhel-1526.patch Patch1002: 1002-checkpoint-Fix-segfault-crash-when-rollback-rhel-1526.patch
Patch1003: 1003-better-way-for-dns-changes-RHEL-14889.patch Patch1003: 1003-better-way-for-dns-changes-RHEL-14889.patch
Patch1004: 1004-bridge-skip-VLAN-filtering-resetting-in-reapply-RHEL-25061.patch
Requires(post): systemd Requires(post): systemd
%if 0%{?fedora} || 0%{?rhel} >= 8 %if 0%{?fedora} || 0%{?rhel} >= 8
@ -1254,6 +1255,9 @@ fi
%changelog %changelog
* Wed Feb 21 2024 Fernando Fernandez Mancera <ferferna@redhat.com> - 1:1.44.0-5
- skip VLAN filtering resetting in reapply if no vlan change changed (RHEL-25061)
* Fri Nov 17 2023 Íñigo Huguet <ihuguet@redhat.com> - 1:1.44.0-4 * Fri Nov 17 2023 Íñigo Huguet <ihuguet@redhat.com> - 1:1.44.0-4
- Add 'dns-change' dispatch event (RHEL-14889) - Add 'dns-change' dispatch event (RHEL-14889)

Loading…
Cancel
Save