mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-14 20:18:39 +00:00
bridge: force (hack)-set of the MTU when explicitly set in the profile
Kernel does a auto-mtu adjusting process whenever a port is added/removed from the bridge, this can cause issues when NM wants to explicitly set an MTU which is equal to the bridge default one (1500) because if later a port is added with a different MTU the kernel will assign the bridge that port's MTU resulting in the bridge runtime configuration differing from the bridge's NM connection profile. What we can do is to always apply the MTU manually for the bridge (if explicitly set by the profile), after doing so the kernel won't modify the MTU anymore, which is what we want, problem is that kernel won't actually apply the MTU to the netdev if it's not actually changing so we first apply it to MTU-1 and then to the desired value. https://bugzilla.redhat.com/show_bug.cgi?id=1778590 Signed-off-by: Antonio Cardace <acardace@redhat.com>
This commit is contained in:
parent
516c623618
commit
e23798a5e5
|
@ -1103,6 +1103,12 @@ create_and_realize(NMDevice * device,
|
|||
|
||||
to_sysfs_group_address_sys(nm_setting_bridge_get_group_address(s_bridge), &props.group_addr);
|
||||
|
||||
/* If mtu != 0, we set the MTU of the new bridge at creation time. However, kernel will still
|
||||
* automatically adjust the MTU of the bridge based on the minimum of the slave's MTU.
|
||||
* We don't want this automatism as the user asked for a fixed MTU.
|
||||
*
|
||||
* To workaround this behavior of kernel, we will later toggle the MTU twice. See
|
||||
* NMDeviceClass.mtu_force_set. */
|
||||
r = nm_platform_link_bridge_add(nm_device_get_platform(device),
|
||||
iface,
|
||||
hwaddr ? mac_address : NULL,
|
||||
|
@ -1159,6 +1165,7 @@ nm_device_bridge_class_init(NMDeviceBridgeClass *klass)
|
|||
device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_BRIDGE);
|
||||
|
||||
device_class->is_master = TRUE;
|
||||
device_class->mtu_force_set = TRUE;
|
||||
device_class->get_generic_capabilities = get_generic_capabilities;
|
||||
device_class->check_connection_compatible = check_connection_compatible;
|
||||
device_class->check_connection_available = check_connection_available;
|
||||
|
|
|
@ -661,6 +661,8 @@ typedef struct _NMDevicePrivate {
|
|||
guint64 tx_bytes;
|
||||
guint64 rx_bytes;
|
||||
} stats;
|
||||
|
||||
bool mtu_force_set_done : 1;
|
||||
} NMDevicePrivate;
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE(NMDevice, nm_device, NM_TYPE_DBUS_OBJECT)
|
||||
|
@ -10419,6 +10421,18 @@ _commit_mtu(NMDevice *self, const NMIP4Config *config)
|
|||
}
|
||||
}
|
||||
|
||||
if (mtu_desired && NM_DEVICE_GET_CLASS(self)->mtu_force_set && !priv->mtu_force_set_done) {
|
||||
priv->mtu_force_set_done = TRUE;
|
||||
|
||||
if (mtu_desired == mtu_plat) {
|
||||
mtu_plat--;
|
||||
if (NM_DEVICE_GET_CLASS(self)->set_platform_mtu(self, mtu_desired - 1)) {
|
||||
_LOGD(LOGD_DEVICE, "mtu: force-set MTU to %u", mtu_desired - 1);
|
||||
} else
|
||||
_LOGW(LOGD_DEVICE, "mtu: failure to force-set MTU to %u", mtu_desired - 1);
|
||||
}
|
||||
}
|
||||
|
||||
_LOGT(LOGD_DEVICE,
|
||||
"mtu: device-mtu: %u%s, ipv6-mtu: %u%s, ifindex: %d",
|
||||
(guint) mtu_desired,
|
||||
|
@ -15644,6 +15658,8 @@ _cleanup_generic_post(NMDevice *self, CleanupType cleanup_type)
|
|||
|
||||
priv->linklocal6_dad_counter = 0;
|
||||
|
||||
priv->mtu_force_set_done = FALSE;
|
||||
|
||||
/* Clean up IP configs; this does not actually deconfigure the
|
||||
* interface; the caller must flush routes and addresses explicitly.
|
||||
*/
|
||||
|
|
|
@ -232,6 +232,17 @@ typedef struct _NMDeviceClass {
|
|||
* type (NMDeviceClass), not the actual device instance. */
|
||||
bool is_master : 1;
|
||||
|
||||
/* Force setting the MTU actually means first setting the MTU
|
||||
* to (desired_MTU-1) and then setting the desired_MTU
|
||||
* so that kernel actually applies the MTU, otherwise
|
||||
* kernel will ignore the request if the link's MTU is the
|
||||
* same as the desired one.
|
||||
*
|
||||
* This is just a workaround made for bridges (ATM) that employ
|
||||
* a auto-MTU adjust mechanism if no MTU is manually set.
|
||||
*/
|
||||
bool mtu_force_set : 1;
|
||||
|
||||
void (*state_changed)(NMDevice * device,
|
||||
NMDeviceState new_state,
|
||||
NMDeviceState old_state,
|
||||
|
|
Loading…
Reference in a new issue