diff options
Diffstat (limited to 'src/core/devices')
| -rw-r--r-- | src/core/devices/nm-device-bridge.c | 79 | ||||
| -rw-r--r-- | src/core/devices/nm-device.c | 52 |
2 files changed, 104 insertions, 27 deletions
diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c index 193b655c..ab3a6be9 100644 --- a/src/core/devices/nm-device-bridge.c +++ b/src/core/devices/nm-device-bridge.c @@ -619,7 +619,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; @@ -660,31 +680,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. */ + 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. */ - 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})); - - /* 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 @@ -743,7 +769,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; @@ -757,7 +783,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 @@ -768,7 +794,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; } @@ -910,7 +936,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; @@ -1125,8 +1151,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/devices/nm-device.c b/src/core/devices/nm-device.c index 16f8e1f2..a9e8c085 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -2185,6 +2185,52 @@ out_good: return result; } +static guint8 +_prop_get_ipv4_dhcp_dscp(NMDevice *self, gboolean *out_dscp_explicit) +{ + gs_free_error GError *error = NULL; + NMConnection *connection; + NMSettingIPConfig *s_ip; + const char *str; + + connection = nm_device_get_applied_connection(self); + s_ip = nm_connection_get_setting_ip_config(connection, AF_INET); + g_return_val_if_fail(s_ip, 0); + + NM_SET_OUT(out_dscp_explicit, TRUE); + + str = nm_setting_ip_config_get_dhcp_dscp(s_ip); + if (str) { + nm_assert(nm_utils_validate_dhcp_dscp(str, NULL)); + } else { + str = nm_config_data_get_connection_default(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("ipv4.dhcp-dscp"), + self); + if (!str || !str[0]) { + str = "CS0"; + NM_SET_OUT(out_dscp_explicit, FALSE); + } else if (!nm_utils_validate_dhcp_dscp(str, &error)) { + _LOGW(LOGD_DEVICE, + "invalid global default value '%s' for ipv4.%s: %s", + str, + NM_SETTING_IP_CONFIG_DHCP_DSCP, + error->message); + str = "CS0"; + NM_SET_OUT(out_dscp_explicit, FALSE); + } + } + + if (nm_streq(str, "CS0")) { + return 0; + } else if (nm_streq(str, "CS6")) { + return 0x30; + } else if (nm_streq(str, "CS4")) { + return 0x20; + }; + + return nm_assert_unreachable_val(0); +} + static GBytes * _prop_get_ipv4_dhcp_vendor_class_identifier(NMDevice *self, NMSettingIP4Config *s_ip4) { @@ -10970,8 +11016,11 @@ _dev_ipdhcpx_start(NMDevice *self, int addr_family) const char *hostname; gboolean hostname_is_fqdn; gboolean send_client_id; + guint8 dscp; + gboolean dscp_explicit = FALSE; client_id = _prop_get_ipv4_dhcp_client_id(self, connection, hwaddr, &send_client_id); + dscp = _prop_get_ipv4_dhcp_dscp(self, &dscp_explicit); vendor_class_identifier = _prop_get_ipv4_dhcp_vendor_class_identifier(self, NM_SETTING_IP4_CONFIG(s_ip)); @@ -11010,6 +11059,8 @@ _dev_ipdhcpx_start(NMDevice *self, int addr_family) .request_broadcast = request_broadcast, .acd_timeout_msec = _prop_get_ipv4_dad_timeout(self), .send_client_id = send_client_id, + .dscp = dscp, + .dscp_explicit = dscp_explicit, }, .previous_lease = priv->l3cds[L3_CONFIG_DATA_TYPE_DHCP_X(IS_IPv4)].d, }; @@ -13369,6 +13420,7 @@ can_reapply_change(NMDevice *self, NM_SETTING_CONNECTION_STABLE_ID, NM_SETTING_CONNECTION_AUTOCONNECT, NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES, + NM_SETTING_CONNECTION_AUTOCONNECT_PORTS, NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, NM_SETTING_CONNECTION_ZONE, NM_SETTING_CONNECTION_METERED, |