diff options
29 files changed, 573 insertions, 248 deletions
diff --git a/NEWS b/NEWS index 6d2ab52a..cb32853c 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,16 @@ =============================================== +NetworkManager-1.54.2 +Overview of changes since NetworkManager-1.54.1 +=============================================== + +* Support reapplying the "sriov.vfs" property as long as + "sriov.total-vfs" is not changed. +* Support configuring the HSR protocol version via the + "hsr.protocol-version" property. +* Support configuring the HSR interlink port via the + "hsr.interlink" property. + +=============================================== NetworkManager-1.54.1 Overview of changes since NetworkManager-1.54.0 =============================================== diff --git a/examples/C/glib/monitor-nm-state-gdbus.c b/examples/C/glib/monitor-nm-state-gdbus.c index 927c966c..9ef8757d 100644 --- a/examples/C/glib/monitor-nm-state-gdbus.c +++ b/examples/C/glib/monitor-nm-state-gdbus.c @@ -23,8 +23,8 @@ static const char * nm_state_to_string(NMState state) { switch (state) { - case NM_STATE_ASLEEP: - return "asleep"; + case NM_STATE_DISABLED: + return "network off"; case NM_STATE_CONNECTING: return "connecting"; case NM_STATE_CONNECTED_LOCAL: diff --git a/man/nm-openvswitch.xml b/man/nm-openvswitch.xml index ff852129..82bcba50 100644 --- a/man/nm-openvswitch.xml +++ b/man/nm-openvswitch.xml @@ -91,6 +91,10 @@ NetworkManager inserts the records for Bridges into OVSDB when a Port is attached. </para> + + <para>Known limitation: when the last NetworkManager's owned port is removed, + the bridge is removed too, even if there are other externally attached ports. + </para> </refsect2> <refsect2> @@ -102,6 +106,10 @@ exist. Ports can also be configured to do VLAN tagging or Bonding. NetworkManager inserts the records for Ports into OVSDB when an Interface is attached. Ports must be attached to a Bridge.</para> + + <para>Known limitation: when the last NetworkManager's owned interface is removed, + the port is removed too, even if there are other externally attached interfaces. + </para> </refsect2> <refsect2> diff --git a/meson.build b/meson.build index c256823e..298cbb85 100644 --- a/meson.build +++ b/meson.build @@ -5,7 +5,7 @@ project( # NOTE: When incrementing version also add corresponding # NM_VERSION_x_y_z macros in # "src/libnm-core-public/nm-version-macros.h.in" - version: '1.54.1', + version: '1.54.2', license: 'GPL2+', default_options: [ 'buildtype=debugoptimized', diff --git a/src/core/devices/nm-device-hsr.c b/src/core/devices/nm-device-hsr.c index 59454ee3..e3368a5b 100644 --- a/src/core/devices/nm-device-hsr.c +++ b/src/core/devices/nm-device-hsr.c @@ -116,29 +116,51 @@ create_and_realize(NMDevice *device, const NMPlatformLink **out_plink, GError **error) { - const char *iface = nm_device_get_iface(device); - NMSettingHsr *s_hsr; - NMPlatformLnkHsr lnk = {}; - int r; + const char *iface = nm_device_get_iface(device); + nm_auto_free char *err_msg = NULL; + NMSettingHsr *s_hsr; + NMPlatformLnkHsr lnk = {}; + int r = 0; s_hsr = _nm_connection_get_setting(connection, NM_TYPE_SETTING_HSR); + nm_assert(s_hsr); if (nm_setting_hsr_get_port1(s_hsr) != NULL) lnk.port1 = nm_platform_link_get_ifindex(NM_PLATFORM_GET, nm_setting_hsr_get_port1(s_hsr)); if (nm_setting_hsr_get_port2(s_hsr) != NULL) lnk.port2 = nm_platform_link_get_ifindex(NM_PLATFORM_GET, nm_setting_hsr_get_port2(s_hsr)); - lnk.multicast_spec = nm_setting_hsr_get_multicast_spec(s_hsr); - lnk.prp = nm_setting_hsr_get_prp(s_hsr); + if (nm_setting_hsr_get_interlink(s_hsr) != NULL) { + const char *ifname = nm_setting_hsr_get_interlink(s_hsr); + int ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, ifname); + + if (ifindex <= 0) { + err_msg = g_strdup_printf("interlink port '%s' does not exist", ifname); + goto out; + } + + lnk.interlink = ifindex; + } + + lnk.multicast_spec = nm_setting_hsr_get_multicast_spec(s_hsr); + lnk.prp = nm_setting_hsr_get_prp(s_hsr); + lnk.protocol_version = nm_setting_hsr_get_protocol_version(s_hsr); + r = nm_platform_link_hsr_add(nm_device_get_platform(device), iface, &lnk, out_plink); + if (r < 0) { + err_msg = g_strdup(nm_strerror(r) ?: "unknown"); + } + +out: + if (err_msg) { g_set_error(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, "Failed to create HSR interface '%s' for '%s': %s", iface, nm_connection_get_id(connection), - nm_strerror(r)); + err_msg); return FALSE; } diff --git a/src/core/devices/nm-device-utils.c b/src/core/devices/nm-device-utils.c index 9fd7ac9d..a78499fb 100644 --- a/src/core/devices/nm-device-utils.c +++ b/src/core/devices/nm-device-utils.c @@ -135,13 +135,15 @@ NM_UTILS_LOOKUP_STR_DEFINE( NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_LINK_NOT_INIT, "unmanaged-link-not-init"), NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_QUITTING, "unmanaged-quitting"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_SLEEPING, "unmanaged-sleeping"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_MANAGER_DISABLED, + "unmanaged-nm-disabled"), NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_CONF, "unmanaged-user-conf"), NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_EXPLICIT, "unmanaged-user-explicit"), NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_SETTINGS, "unmanaged-user-settings"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_UDEV, "unmanaged-user-udev"), ); + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_UDEV, "unmanaged-user-udev"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NETWORKING_OFF, "networking-off"), ); NM_UTILS_LOOKUP_STR_DEFINE(nm_device_mtu_source_to_string, NMDeviceMtuSource, diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 79b1076d..6bba982a 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -692,6 +692,8 @@ typedef struct _NMDevicePrivate { IPDevStateData ipdev_data_unspec; + gulong sharing_ipv4_changed_id; + struct { /* If we set the addrgenmode6, this records the previously set value. */ guint8 previous_mode_val; @@ -779,7 +781,6 @@ typedef struct _NMDevicePrivate { char *prop_ip_iface; /* IP interface D-Bus property */ GList *ping_operations; GSource *ping_timeout; - bool refresh_forwarding_done : 1; } NMDevicePrivate; G_DEFINE_ABSTRACT_TYPE(NMDevice, nm_device, NM_TYPE_DBUS_OBJECT) @@ -867,6 +868,8 @@ static void _dev_ipshared4_spawn_dnsmasq(NMDevice *self); static void _dev_ipshared6_start(NMDevice *self); +static void _dev_ipforwarding4_start(NMDevice *self, int addr_family); + static void _cleanup_ip_pre(NMDevice *self, int addr_family, CleanupType cleanup_type, gboolean preserve_dhcp); @@ -2131,8 +2134,8 @@ _prop_get_ipvx_dhcp_send_hostname(NMDevice *self, int addr_family) return send_hostname_v2; } -NMSettingIPConfigForwarding -nm_device_get_ipv4_forwarding(NMDevice *self) +static NMSettingIPConfigForwarding +_prop_get_ipv4_forwarding(NMDevice *self) { NMSettingIPConfig *s_ip; NMSettingIPConfigForwarding forwarding; @@ -3778,7 +3781,7 @@ nm_device_assume_state_reset(NMDevice *self) /*****************************************************************************/ -char * +static char * nm_device_sysctl_ip_conf_get(NMDevice *self, int addr_family, const char *property) { const char *ifname; @@ -6645,7 +6648,7 @@ concheck_update_state(NMDevice *self, } } -const char * +static const char * nm_device_get_effective_ip_config_method(NMDevice *self, int addr_family) { NMDeviceClass *klass; @@ -8639,6 +8642,8 @@ nm_device_unrealize(NMDevice *self, gboolean remove_resources, GError **error) g_object_thaw_notify(G_OBJECT(self)); + nm_device_managed_type_set(self, NM_DEVICE_MANAGED_TYPE_REMOVED); + nm_device_set_unmanaged_flags(self, NM_UNMANAGED_PLATFORM_INIT, TRUE); nm_device_set_unmanaged_flags(self, @@ -10394,6 +10399,43 @@ sriov_params_cb(GError *error, gpointer user_data) nm_device_activate_schedule_stage1_device_prepare(self, FALSE); } +static gboolean +sriov_gen_platform_vfs(NMDevice *self, + NMSettingSriov *s_sriov, + NMPlatformVF ***plat_vfs_out, + GError **error) +{ + nm_auto_freev NMPlatformVF **plat_vfs = NULL; + guint num; + + nm_assert(s_sriov); + nm_assert(plat_vfs_out && !*plat_vfs_out); + + num = nm_setting_sriov_get_num_vfs(s_sriov); + plat_vfs = g_new0(NMPlatformVF *, num + 1); + + for (int i = 0; i < num; i++) { + NMSriovVF *vf = nm_setting_sriov_get_vf(s_sriov, i); + gs_free_error GError *local = NULL; + + plat_vfs[i] = sriov_vf_config_to_platform(self, vf, &local); + + if (!plat_vfs[i]) { + g_set_error(error, + local->domain, + local->code, + "VF '%s' is invalid: %s", + nm_utils_sriov_vf_to_str(vf, FALSE, NULL), + local->message); + return FALSE; + } + } + + *plat_vfs_out = g_steal_pointer(&plat_vfs); + + return TRUE; +} + /* * activate_stage1_device_prepare * @@ -10440,10 +10482,7 @@ activate_stage1_device_prepare(NMDevice *self) if (s_sriov && nm_device_has_capability(self, NM_DEVICE_CAP_SRIOV)) { nm_auto_freev NMPlatformVF **plat_vfs = NULL; gs_free_error GError *error = NULL; - NMSriovVF *vf; NMTernary autoprobe; - guint num; - guint i; autoprobe = nm_setting_sriov_get_autoprobe_drivers(s_sriov); if (autoprobe == NM_TERNARY_DEFAULT) { @@ -10456,21 +10495,12 @@ activate_stage1_device_prepare(NMDevice *self) NM_OPTION_BOOL_TRUE); } - num = nm_setting_sriov_get_num_vfs(s_sriov); - plat_vfs = g_new0(NMPlatformVF *, num + 1); - for (i = 0; i < num; i++) { - vf = nm_setting_sriov_get_vf(s_sriov, i); - plat_vfs[i] = sriov_vf_config_to_platform(self, vf, &error); - if (!plat_vfs[i]) { - _LOGE(LOGD_DEVICE, - "failed to apply SR-IOV VF '%s': %s", - nm_utils_sriov_vf_to_str(vf, FALSE, NULL), - error->message); - nm_device_state_changed(self, - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED); - return; - } + if (!sriov_gen_platform_vfs(self, s_sriov, &plat_vfs, &error)) { + _LOGE(LOGD_DEVICE, "cannot parse the VF list: %s", error->message); + nm_device_state_changed(self, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED); + return; } /* When changing the number of VFs the kernel can block @@ -13139,17 +13169,12 @@ activate_stage3_ip_config_for_addr_family(NMDevice *self, int addr_family) goto out_devip; if (IS_IPv4) { - NMSettingIPConfigForwarding ipv4_forwarding = nm_device_get_ipv4_forwarding(self); - - if (NM_IN_SET(ipv4_forwarding, - NM_SETTING_IP_CONFIG_FORWARDING_NO, - NM_SETTING_IP_CONFIG_FORWARDING_YES)) { - nm_device_sysctl_ip_conf_set(self, AF_INET, "forwarding", ipv4_forwarding ? "1" : "0"); - } priv->ipll_data_4.v4.mode = _prop_get_ipv4_link_local(self); if (priv->ipll_data_4.v4.mode == NM_SETTING_IP4_LL_ENABLED) _dev_ipll4_start(self); + _dev_ipforwarding4_start(self, addr_family); + if (nm_streq(priv->ipv4_method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) _dev_ipdhcpx_start(self, AF_INET); else if (nm_streq(priv->ipv4_method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { @@ -13469,15 +13494,21 @@ nm_device_activate_schedule_stage3_ip_config(NMDevice *self, gboolean do_sync) static void _dev_ipsharedx_set_state(NMDevice *self, int addr_family, NMDeviceIPState state) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - const int IS_IPv4 = NM_IS_IPv4(addr_family); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + const int IS_IPv4 = NM_IS_IPv4(addr_family); + NMDeviceIPState old_state = priv->ipshared_data_x[IS_IPv4].state; - if (priv->ipshared_data_x[IS_IPv4].state != state) { + if (old_state != state) { _LOGD_ipshared(addr_family, "set state %s (was %s)", nm_device_ip_state_to_string(state), - nm_device_ip_state_to_string(priv->ipshared_data_x[IS_IPv4].state)); + nm_device_ip_state_to_string(old_state)); priv->ipshared_data_x[IS_IPv4].state = state; + + if (old_state == NM_DEVICE_IP_STATE_READY || state == NM_DEVICE_IP_STATE_READY) + nm_manager_update_shared_connection(NM_MANAGER_GET, + addr_family, + state == NM_DEVICE_IP_STATE_READY); } } @@ -13772,6 +13803,106 @@ _dev_ipshared6_start(NMDevice *self) /*****************************************************************************/ +/** + * Set the device's forwarding to the specified value. If %NM_TERNARY_DEFAULT is specified, + * it's set to the kernel's default, otherwise it's set to the specific value. + */ +static void +_dev_ipforwarding4_set(NMDevice *self, NMTernary val) +{ + gs_free const char *default_forwarding = NULL; + gs_free const char *current_forwarding = NULL; + const char *val_str; + + if (val != NM_TERNARY_DEFAULT) { + val_str = val ? "1" : "0"; + } else { + default_forwarding = nm_platform_sysctl_get( + nm_device_get_platform(self), + NMP_SYSCTL_PATHID_ABSOLUTE("/proc/sys/net/ipv4/conf/default/forwarding")); + + if (!default_forwarding) { + _LOGW(LOGD_DEVICE, + "error setting IPv4 forwarding: can't read default forwarding value: %s", + nm_strerror_native(errno)); + return; /* Non fatal */ + } + + val_str = default_forwarding; + } + + current_forwarding = nm_device_sysctl_ip_conf_get(self, AF_INET, "forwarding"); + if (nm_streq0(current_forwarding, val_str)) + return; + + if (!nm_device_sysctl_ip_conf_set(self, AF_INET, "forwarding", val_str)) + _LOGW(LOGD_DEVICE, + "error setting IPv4 forwarding to '%s': %s", + val_str, + nm_strerror_native(errno)); +} + +static void +_dev_ipforwarding4_auto_cb(NMManager *manager, gboolean sharing_ipv4, gpointer data) +{ + NMDevice *self = NM_DEVICE(data); + + _dev_ipforwarding4_set(self, sharing_ipv4 ? NM_TERNARY_TRUE : NM_TERNARY_DEFAULT); +} + +static void +_dev_ipforwarding4_start(NMDevice *self, int addr_family) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMSettingIPConfigForwarding ipv4_forwarding = _prop_get_ipv4_forwarding(self); + NMTernary new_forwarding = NM_TERNARY_DEFAULT; + + /* IPv6 per-interface forwarding not supported yet */ + if (addr_family != AF_INET) + return; + + if (nm_streq(priv->ipv4_method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { + new_forwarding = NM_TERNARY_TRUE; + } else if (ipv4_forwarding == NM_SETTING_IP_CONFIG_FORWARDING_YES) { + new_forwarding = NM_TERNARY_TRUE; + } else if (ipv4_forwarding == NM_SETTING_IP_CONFIG_FORWARDING_NO) { + new_forwarding = NM_TERNARY_FALSE; + } else if (ipv4_forwarding == NM_SETTING_IP_CONFIG_FORWARDING_AUTO) { + if (nm_manager_get_sharing_ipv4(NM_MANAGER_GET)) + new_forwarding = NM_TERNARY_TRUE; + else + new_forwarding = NM_TERNARY_DEFAULT; + + if (!priv->sharing_ipv4_changed_id) + priv->sharing_ipv4_changed_id = g_signal_connect(NM_MANAGER_GET, + NM_MANAGER_SHARING_IPV4_CHANGED, + G_CALLBACK(_dev_ipforwarding4_auto_cb), + self); + } else { + nm_assert_not_reached(); + } + + _dev_ipforwarding4_set(self, new_forwarding); +} + +static void +_dev_ipforwarding_cleanup(NMDevice *self, int addr_family, CleanupType cleanup_type) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + + if (!NM_IS_IPv4(addr_family)) + return; + + nm_clear_g_signal_handler(NM_MANAGER_GET, &priv->sharing_ipv4_changed_id); + + if (NM_IN_SET(cleanup_type, CLEANUP_TYPE_DECONFIGURE, CLEANUP_TYPE_KEEP_REAPPLY)) { + /* Deconfigure by restoring kernel's default */ + _dev_ipforwarding4_set(self, NM_TERNARY_DEFAULT); + } +} + +/*****************************************************************************/ + static void act_request_set(NMDevice *self, NMActRequest *act_request) { @@ -13884,6 +14015,8 @@ _cleanup_ip_pre(NMDevice *self, int addr_family, CleanupType cleanup_type, gbool NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); gboolean keep_reapply = (cleanup_type == CLEANUP_TYPE_KEEP_REAPPLY); + _dev_ipforwarding_cleanup(self, addr_family, cleanup_type); + _dev_ipsharedx_cleanup(self, addr_family); _dev_ipdev_cleanup(self, AF_UNSPEC); @@ -14066,7 +14199,8 @@ can_reapply_change(NMDevice *self, return nm_device_hash_check_invalid_keys(diffs, NM_SETTING_SRIOV_SETTING_NAME, error, - NM_SETTING_SRIOV_PRESERVE_ON_DOWN); + NM_SETTING_SRIOV_PRESERVE_ON_DOWN, + NM_SETTING_SRIOV_VFS); } out_fail: @@ -14244,9 +14378,35 @@ check_and_reapply_connection(NMDevice *self, nm_device_link_properties_set(self, TRUE); - if (priv->state >= NM_DEVICE_STATE_CONFIG) + if (priv->state >= NM_DEVICE_STATE_CONFIG) { + GHashTable *sriov_diff; + lldp_setup(self, NM_TERNARY_DEFAULT); + sriov_diff = nm_g_hash_table_lookup(diffs, NM_SETTING_SRIOV_SETTING_NAME); + + if (sriov_diff && nm_g_hash_table_lookup(sriov_diff, NM_SETTING_SRIOV_VFS)) { + nm_auto_freev NMPlatformVF **plat_vfs = NULL; + NMSettingSriov *s_sriov; + + s_sriov = (NMSettingSriov *) nm_connection_get_setting(applied, NM_TYPE_SETTING_SRIOV); + + if (s_sriov) { + gs_free_error GError *local = NULL; + + if (!sriov_gen_platform_vfs(self, s_sriov, &plat_vfs, &local) + || !nm_platform_link_set_sriov_vfs(nm_device_get_platform(self), + priv->ifindex, + (const NMPlatformVF *const *) plat_vfs)) { + _LOGE(LOGD_DEVICE, + "failed to reapply SRIOV VFs%s%s", + local ? ": " : "", + local ? local->message : ""); + } + } + } + } + if (priv->state >= NM_DEVICE_STATE_IP_CONFIG) { /* Allow reapply of MTU */ priv->mtu_source = NM_DEVICE_MTU_SOURCE_NONE; @@ -15613,7 +15773,7 @@ nm_device_get_firmware_missing(NMDevice *self) NM_UTILS_FLAGS2STR_DEFINE(nm_unmanaged_flags2str, NMUnmanagedFlags, - NM_UTILS_FLAGS2STR(NM_UNMANAGED_SLEEPING, "sleeping"), + NM_UTILS_FLAGS2STR(NM_UNMANAGED_MANAGER_DISABLED, "nm-disabled"), NM_UTILS_FLAGS2STR(NM_UNMANAGED_QUITTING, "quitting"), NM_UTILS_FLAGS2STR(NM_UNMANAGED_PLATFORM_INIT, "platform-init"), NM_UTILS_FLAGS2STR(NM_UNMANAGED_USER_EXPLICIT, "user-explicit"), @@ -15677,8 +15837,8 @@ unmanaged_flags_to_reason(NMUnmanagedFlags flags) /* Even if there are multiple flags, we can only return one reason. * Return the most important reason. */ - if (NM_FLAGS_HAS(flags, NM_UNMANAGED_SLEEPING)) - return NM_DEVICE_STATE_REASON_UNMANAGED_SLEEPING; + if (NM_FLAGS_HAS(flags, NM_UNMANAGED_MANAGER_DISABLED)) + return NM_DEVICE_STATE_REASON_UNMANAGED_MANAGER_DISABLED; if (NM_FLAGS_HAS(flags, NM_UNMANAGED_QUITTING)) return NM_DEVICE_STATE_REASON_UNMANAGED_QUITTING; if (NM_FLAGS_HAS(flags, NM_UNMANAGED_USER_SETTINGS)) @@ -16923,8 +17083,6 @@ _cleanup_generic_post(NMDevice *self, NMDeviceStateReason reason, CleanupType cl priv->v4_route_table_all_sync_before = FALSE; priv->v6_route_table_all_sync_before = FALSE; - priv->refresh_forwarding_done = FALSE; - priv->mtu_force_set_done = FALSE; priv->needs_ip6_subnet = FALSE; @@ -16970,7 +17128,6 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu NMDevicePrivate *priv; NMDeviceClass *klass = NM_DEVICE_GET_CLASS(self); int ifindex; - gint32 default_forwarding_v4; g_return_if_fail(NM_IS_DEVICE(self)); @@ -16993,17 +17150,6 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu nm_device_sysctl_ip_conf_set(self, AF_INET6, "use_tempaddr", "0"); } - /* Restoring the device's forwarding to the sysctl default is necessary because - * `refresh_forwarding()` only updates forwarding on activated devices. */ - default_forwarding_v4 = nm_platform_sysctl_get_int32( - nm_device_get_platform(self), - NMP_SYSCTL_PATHID_ABSOLUTE("/proc/sys/net/ipv4/conf/default/forwarding"), - 0); - nm_device_sysctl_ip_conf_set(self, - AF_INET, - "forwarding", - default_forwarding_v4 == 1 ? "1" : "0"); - /* Call device type-specific deactivation */ if (klass->deactivate) klass->deactivate(self); @@ -18947,19 +19093,6 @@ nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean return nm_assert_unreachable_val(NULL); } -gboolean -nm_device_get_refresh_forwarding_done(NMDevice *self) -{ - return NM_DEVICE_GET_PRIVATE(self)->refresh_forwarding_done; -} - -void -nm_device_set_refresh_forwarding_done(NMDevice *self, gboolean is_refresh_forwarding_done) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - priv->refresh_forwarding_done = is_refresh_forwarding_done; -} - /*****************************************************************************/ static const char * diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h index 9a663c2a..8632944a 100644 --- a/src/core/devices/nm-device.h +++ b/src/core/devices/nm-device.h @@ -581,7 +581,8 @@ void nm_device_copy_ip6_dns_config(NMDevice *self, NMDevice *from_device); /** * NMUnmanagedFlags: * @NM_UNMANAGED_NONE: placeholder value - * @NM_UNMANAGED_SLEEPING: %TRUE when unmanaged because NM is sleeping. + * @NM_UNMANAGED_MANAGER_DISABLED: %TRUE when unmanaged because NM is disabled. + * Currently, this happens when sleeping or with networking disabled. * @NM_UNMANAGED_QUITTING: %TRUE when unmanaged because NM is shutting down. * @NM_UNMANAGED_PLATFORM_INIT: %TRUE when unmanaged because platform link not * yet initialized. Unrealized device are also unmanaged for this reason. @@ -610,11 +611,11 @@ typedef enum { /* these flags are authoritative. If one of them is set, * the device cannot be managed. */ - NM_UNMANAGED_SLEEPING = (1LL << 0), - NM_UNMANAGED_QUITTING = (1LL << 1), - NM_UNMANAGED_PLATFORM_INIT = (1LL << 2), - NM_UNMANAGED_USER_EXPLICIT = (1LL << 3), - NM_UNMANAGED_USER_SETTINGS = (1LL << 4), + NM_UNMANAGED_MANAGER_DISABLED = (1LL << 0), + NM_UNMANAGED_QUITTING = (1LL << 1), + NM_UNMANAGED_PLATFORM_INIT = (1LL << 2), + NM_UNMANAGED_USER_EXPLICIT = (1LL << 3), + NM_UNMANAGED_USER_SETTINGS = (1LL << 4), /* These flags can be non-effective and be overwritten * by other flags. */ @@ -852,14 +853,4 @@ void nm_routing_rules_sync(NMConnection *applied_connection, NMDevice *self, NMNetns *netns); -NMSettingIPConfigForwarding nm_device_get_ipv4_forwarding(NMDevice *self); - -const char *nm_device_get_effective_ip_config_method(NMDevice *self, int addr_family); - -char *nm_device_sysctl_ip_conf_get(NMDevice *self, int addr_family, const char *property); - -gboolean nm_device_get_refresh_forwarding_done(NMDevice *self); - -void nm_device_set_refresh_forwarding_done(NMDevice *self, gboolean is_refresh_forwarding_done); - #endif /* __NETWORKMANAGER_DEVICE_H__ */ diff --git a/src/core/devices/ovs/nm-ovsdb.c b/src/core/devices/ovs/nm-ovsdb.c index 164bfd35..1c9484c4 100644 --- a/src/core/devices/ovs/nm-ovsdb.c +++ b/src/core/devices/ovs/nm-ovsdb.c @@ -1460,40 +1460,42 @@ _delete_interface(NMOvsdb *self, json_t *params, const char *ifname) json_array_append_new(new_interfaces, json_pack("[s,s]", "uuid", interface_uuid)); } - if (num_nm_interfaces == 0) { - /* The port no longer has any NM interface. Don't add it to "new_ports" and set - * ports_changed=TRUE, so that it will be deleted. */ + if (interfaces_changed && num_nm_interfaces == 0) { + /* We are deleting the last nm-interface of this port. Don't add it to "new_ports" + * and set ports_changed=TRUE, so that it will be deleted. */ ports_changed = TRUE; } else { + /* Keep this port: it's still alive, or it's unrelated to the deleted interface */ + json_array_append_new(new_ports, json_pack("[s,s]", "uuid", port_uuid)); + if (ovs_port->connection_uuid) + num_nm_ports++; + if (interfaces_changed) { - /* An interface needs to be deleted from this port */ + /* This port is still alive, but an interface needs to be deleted from it */ _expect_port_interfaces(params, ovs_port->name, interfaces); _set_port_interfaces(params, ovs_port->name, new_interfaces); } - /* The port is still alive */ - json_array_append_new(new_ports, json_pack("[s,s]", "uuid", port_uuid)); - if (ovs_port->connection_uuid) - num_nm_ports++; } } - if (num_nm_ports == 0) { - /* The bridge no longer has any NM port. Don't add it to "new_bridges" and set - * bridges_changed=TRUE, so that it will be deleted. */ + if (ports_changed && num_nm_ports == 0) { + /* We are deleting the last nm-port of this bridge. Don't add it to "new_bridges" + * and set bridges_changed=TRUE, so that it will be deleted. */ bridges_changed = TRUE; } else { + /* Keep this bridge: it's still alive, or it's unrelated to the deleted interface */ + json_array_append_new(new_bridges, json_pack("[s,s]", "uuid", ovs_bridge->bridge_uuid)); + if (ports_changed) { - /* A port needs to be deleted from this bridge */ + /* This bridge is still alive, but a port needs to be deleted from it */ _expect_bridge_ports(params, ovs_bridge->name, ports); _set_bridge_ports(params, ovs_bridge->name, new_ports); } - /* The bridge is still alive */ - json_array_append_new(new_bridges, json_pack("[s,s]", "uuid", ovs_bridge->bridge_uuid)); } } if (bridges_changed) { - /* A port needs to be deleted from this bridge */ + /* A bridge needs to be deleted */ _expect_ovs_bridges(params, priv->db_uuid, bridges); _set_ovs_bridges(params, priv->db_uuid, new_bridges); } diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c index 9dc7bc01..87dde2c3 100644 --- a/src/core/nm-manager.c +++ b/src/core/nm-manager.c @@ -136,6 +136,7 @@ enum { ACTIVE_CONNECTION_REMOVED, CONFIGURE_QUIT, DEVICE_IFINDEX_CHANGED, + SHARING_IPV4_CHANGED, LAST_SIGNAL }; @@ -238,6 +239,8 @@ typedef struct { guint8 device_state_prune_ratelimit_count; + guint shared_connections_ip4_count; + bool startup : 1; bool devices_inited : 1; @@ -1960,7 +1963,7 @@ find_device_by_iface(NMManager *self, } static gboolean -manager_sleeping(NMManager *self) +manager_is_disabled(NMManager *self) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self); @@ -1973,8 +1976,8 @@ static const char * _nm_state_to_string(NMState state) { switch (state) { - case NM_STATE_ASLEEP: - return "ASLEEP"; + case NM_STATE_DISABLED: + return "DISABLED"; case NM_STATE_DISCONNECTED: return "DISCONNECTED"; case NM_STATE_DISCONNECTING: @@ -2078,15 +2081,18 @@ nm_manager_update_state(NMManager *self) { NMManagerPrivate *priv; NMState new_state = NM_STATE_DISCONNECTED; + const char *detail = ""; g_return_if_fail(NM_IS_MANAGER(self)); priv = NM_MANAGER_GET_PRIVATE(self); - if (manager_sleeping(self)) - new_state = NM_STATE_ASLEEP; - else + if (manager_is_disabled(self)) { + new_state = NM_STATE_DISABLED; + detail = priv->sleeping ? " (ASLEEP)" : " (NETWORKING OFF)"; + } else { new_state = find_best_device_state(self); + } if (new_state >= NM_STATE_CONNECTED_LOCAL && priv->connectivity_state == NM_CONNECTIVITY_FULL) { new_state = NM_STATE_CONNECTED_GLOBAL; @@ -2097,7 +2103,7 @@ nm_manager_update_state(NMManager *self) priv->state = new_state; - _LOGI(LOGD_CORE, "NetworkManager state is now %s", _nm_state_to_string(new_state)); + _LOGI(LOGD_CORE, "NetworkManager state is now %s%s", _nm_state_to_string(new_state), detail); _notify(self, PROP_STATE); nm_dbus_object_emit_signal(NM_DBUS_OBJECT(self), @@ -2956,7 +2962,7 @@ _rfkill_update_devices(NMManager *self, NMRfkillType rtype, gboolean enabled) _notify(self, _rfkill_type_desc[rtype].prop_id); /* Don't touch devices if asleep/networking disabled */ - if (manager_sleeping(self)) + if (manager_is_disabled(self)) return; /* enable/disable wireless devices as required */ @@ -3120,7 +3126,7 @@ _rfkill_update_from_user(NMManager *self, NMRfkillType rtype, gboolean enabled) gboolean old_enabled, new_enabled; /* Don't touch devices if asleep/networking disabled */ - if (manager_sleeping(self)) + if (manager_is_disabled(self)) return; _LOGD(LOGD_RFKILL, @@ -4079,7 +4085,7 @@ add_device(NMManager *self, NMDevice *device, GError **error) nm_device_set_unmanaged_by_user_settings(device, TRUE); - nm_device_set_unmanaged_flags(device, NM_UNMANAGED_SLEEPING, manager_sleeping(self)); + nm_device_set_unmanaged_flags(device, NM_UNMANAGED_MANAGER_DISABLED, manager_is_disabled(self)); dbus_path = nm_dbus_object_export(NM_DBUS_OBJECT(device)); _LOG2I(LOGD_DEVICE, device, "new %s device (%s)", type_desc, dbus_path); @@ -7299,7 +7305,7 @@ device_sleep_cb(NMDevice *device, GParamSpec *pspec, NMManager *self) case NM_DEVICE_STATE_DISCONNECTED: _LOGD(LOGD_SUSPEND, "sleep: unmanaging device %s", nm_device_get_ip_iface(device)); nm_device_set_unmanaged_by_flags_queue(device, - NM_UNMANAGED_SLEEPING, + NM_UNMANAGED_MANAGER_DISABLED, NM_UNMAN_FLAG_OP_SET_UNMANAGED, NM_DEVICE_STATE_REASON_SLEEPING); break; @@ -7321,24 +7327,26 @@ _handle_device_takedown(NMManager *self, gboolean suspending, gboolean is_shutdown) { + gboolean is_sleep = suspending || is_shutdown; + NMDeviceStateReason reason = + is_sleep ? NM_DEVICE_STATE_REASON_SLEEPING : NM_DEVICE_STATE_REASON_NETWORKING_OFF; + nm_device_notify_sleeping(device); if (nm_device_is_activating(device) || nm_device_get_state(device) == NM_DEVICE_STATE_ACTIVATED) { - _LOGD(LOGD_SUSPEND, + _LOGD(is_sleep ? LOGD_SUSPEND : LOGD_CORE, "%s: wait disconnection of device %s", - is_shutdown ? "shutdown" : "sleep", + is_sleep ? (is_shutdown ? "shutdown" : "sleep") : "networking off", nm_device_get_ip_iface(device)); if (sleep_devices_add(self, device, suspending)) - nm_device_queue_state(device, - NM_DEVICE_STATE_DEACTIVATING, - NM_DEVICE_STATE_REASON_SLEEPING); + nm_device_queue_state(device, NM_DEVICE_STATE_DEACTIVATING, reason); } else { nm_device_set_unmanaged_by_flags(device, - NM_UNMANAGED_SLEEPING, + NM_UNMANAGED_MANAGER_DISABLED, NM_UNMAN_FLAG_OP_SET_UNMANAGED, - NM_DEVICE_STATE_REASON_SLEEPING); + reason); } } @@ -7352,8 +7360,10 @@ do_sleep_wake(NMManager *self, gboolean sleeping_changed) suspending = sleeping_changed && priv->sleeping; waking_from_suspend = sleeping_changed && !priv->sleeping; - if (manager_sleeping(self)) { - _LOGD(LOGD_SUSPEND, "sleep: %s...", suspending ? "sleeping" : "disabling"); + if (manager_is_disabled(self)) { + _LOGD(suspending ? LOGD_SUSPEND : LOGD_CORE, + "%s...", + suspending ? "sleep: sleeping" : "networking: disabling"); /* FIXME: are there still hardware devices that need to be disabled around * suspend/resume? @@ -7379,7 +7389,9 @@ do_sleep_wake(NMManager *self, gboolean sleeping_changed) _handle_device_takedown(self, device, suspending, FALSE); } } else { - _LOGD(LOGD_SUSPEND, "sleep: %s...", waking_from_suspend ? "waking up" : "re-enabling"); + _LOGD(waking_from_suspend ? LOGD_SUSPEND : LOGD_CORE, + "%s...", + waking_from_suspend ? "sleep: waking up" : "networking: re-enabling"); sleep_devices_clear(self); @@ -7393,7 +7405,7 @@ do_sleep_wake(NMManager *self, gboolean sleeping_changed) */ if (device_is_wake_on_lan(priv->platform, device)) nm_device_set_unmanaged_by_flags(device, - NM_UNMANAGED_SLEEPING, + NM_UNMANAGED_MANAGER_DISABLED, NM_UNMAN_FLAG_OP_SET_UNMANAGED, NM_DEVICE_STATE_REASON_SLEEPING); @@ -7421,10 +7433,12 @@ do_sleep_wake(NMManager *self, gboolean sleeping_changed) guint i; if (nm_device_is_software(device) - && !nm_device_get_unmanaged_flags(device, NM_UNMANAGED_SLEEPING)) { + && !nm_device_get_unmanaged_flags(device, NM_UNMANAGED_MANAGER_DISABLED)) { /* DHCP leases of software devices could have gone stale * so we need to renew them. */ - nm_device_update_dynamic_ip_setup(device, "wake up"); + nm_device_update_dynamic_ip_setup(device, + waking_from_suspend ? "wake up" + : "networking on"); continue; } @@ -7455,7 +7469,7 @@ do_sleep_wake(NMManager *self, gboolean sleeping_changed) ? NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED : NM_DEVICE_STATE_REASON_NOW_MANAGED; nm_device_set_unmanaged_by_flags(device, - NM_UNMANAGED_SLEEPING, + NM_UNMANAGED_MANAGER_DISABLED, NM_UNMAN_FLAG_OP_SET_MANAGED, reason); } @@ -8818,6 +8832,41 @@ nm_manager_emit_device_ifindex_changed(NMManager *self, NMDevice *device) g_signal_emit(self, signals[DEVICE_IFINDEX_CHANGED], 0, device); } +void +nm_manager_update_shared_connection(NMManager *self, int addr_family, gboolean enabled) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self); + gboolean state_changed, state; + + /* Only IPv4 supported for the moment */ + if (addr_family != AF_INET) + return; + + if (enabled) { + g_return_if_fail(priv->shared_connections_ip4_count < G_MAXUINT); + priv->shared_connections_ip4_count++; + state_changed = priv->shared_connections_ip4_count == 1; + } else { + g_return_if_fail(priv->shared_connections_ip4_count > 0); + priv->shared_connections_ip4_count--; + state_changed = priv->shared_connections_ip4_count == 0; + } + + if (state_changed) { + state = priv->shared_connections_ip4_count > 0; + _LOGD(LOGD_SHARING, "sharing-ipv4 state change %d -> %d", !state, state); + g_signal_emit(self, signals[SHARING_IPV4_CHANGED], 0, state); + } +} + +gboolean +nm_manager_get_sharing_ipv4(NMManager *self) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self); + + return priv->shared_connections_ip4_count > 0; +} + /*****************************************************************************/ NM_DEFINE_SINGLETON_REGISTER(NMManager); @@ -9921,6 +9970,17 @@ nm_manager_class_init(NMManagerClass *manager_class) G_TYPE_NONE, 1, NM_TYPE_DEVICE); + + signals[SHARING_IPV4_CHANGED] = g_signal_new(NM_MANAGER_SHARING_IPV4_CHANGED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_BOOLEAN); } NMConfig * diff --git a/src/core/nm-manager.h b/src/core/nm-manager.h index 3c5213c4..e10ca0d1 100644 --- a/src/core/nm-manager.h +++ b/src/core/nm-manager.h @@ -61,6 +61,7 @@ #define NM_MANAGER_CONFIGURE_QUIT "configure-quit" #define NM_MANAGER_INTERNAL_DEVICE_ADDED "internal-device-added" #define NM_MANAGER_INTERNAL_DEVICE_REMOVED "internal-device-removed" +#define NM_MANAGER_SHARING_IPV4_CHANGED "sharing-ipv4-changed" GType nm_manager_get_type(void); @@ -212,6 +213,9 @@ struct _NMDnsManager; struct _NMDnsManager *nm_manager_get_dns_manager(NMManager *self); +void nm_manager_update_shared_connection(NMManager *self, int addr_family, gboolean enabled); +gboolean nm_manager_get_sharing_ipv4(NMManager *self); + /*****************************************************************************/ void nm_manager_notify_delete_settings_connections(NMManager *self, diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c index fbcee40d..0288795e 100644 --- a/src/core/nm-policy.c +++ b/src/core/nm-policy.c @@ -18,7 +18,6 @@ #include "NetworkManagerUtils.h" #include "devices/nm-device.h" #include "devices/nm-device-factory.h" -#include "devices/nm-device-private.h" #include "dns/nm-dns-manager.h" #include "nm-act-request.h" #include "nm-auth-utils.h" @@ -98,6 +97,7 @@ typedef struct { bool updating_dns : 1; GArray *ip6_prefix_delegations; /* pool of ip6 prefixes delegated to all devices */ + } NMPolicyPrivate; struct _NMPolicy { @@ -1845,7 +1845,7 @@ nm_policy_device_recheck_auto_activate_schedule(NMPolicy *self, NMDevice *device priv = NM_POLICY_GET_PRIVATE(self); - if (nm_manager_get_state(priv->manager) == NM_STATE_ASLEEP) + if (nm_manager_get_state(priv->manager) == NM_STATE_DISABLED) return; if (!nm_device_autoconnect_allowed(device)) @@ -2084,65 +2084,6 @@ unblock_autoconnect_for_ports_for_sett_conn(NMPolicy *self, NMSettingsConnection } static void -refresh_forwarding(NMPolicy *self, NMDevice *device, gboolean is_activated_shared_device) -{ - NMActiveConnection *ac; - NMDevice *tmp_device; - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self); - const CList *tmp_lst; - gboolean any_shared_active = false; - gint32 default_forwarding_v4; - const char *new_value = NULL; - - /* FIXME: This implementation is still inefficient because refresh_forwarding() - * is called every time a device goes up or down, requiring a full scan of all - * active connections to determine if any shared connection is active. */ - nm_manager_for_each_active_connection (priv->manager, ac, tmp_lst) { - NMSettingIPConfig *s_ip; - NMDevice *to_device = nm_active_connection_get_device(ac); - - if (to_device) { - s_ip = nm_device_get_applied_setting(to_device, NM_TYPE_SETTING_IP4_CONFIG); - if (s_ip) { - if (nm_streq0(nm_device_get_effective_ip_config_method(to_device, AF_INET), - NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { - any_shared_active = true; - break; - } - } - } - } - - default_forwarding_v4 = nm_platform_sysctl_get_int32( - NM_PLATFORM_GET, - NMP_SYSCTL_PATHID_ABSOLUTE("/proc/sys/net/ipv4/conf/default/forwarding"), - 0); - - new_value = any_shared_active ? "1" : (default_forwarding_v4 ? "1" : "0"); - - nm_manager_for_each_device (priv->manager, tmp_device, tmp_lst) { - NMDeviceState state; - NMSettingIPConfigForwarding ipv4_forwarding; - - state = nm_device_get_state(tmp_device); - if (state != NM_DEVICE_STATE_ACTIVATED) - continue; - - ipv4_forwarding = nm_device_get_ipv4_forwarding(tmp_device); - - if (ipv4_forwarding == NM_SETTING_IP_CONFIG_FORWARDING_AUTO - || (device == tmp_device && is_activated_shared_device)) { - gs_free char *sysctl_value = NULL; - - sysctl_value = nm_device_sysctl_ip_conf_get(tmp_device, AF_INET, "forwarding"); - - if (!nm_streq0(sysctl_value, new_value)) - nm_device_sysctl_ip_conf_set(tmp_device, AF_INET, "forwarding", new_value); - } - } -} - -static void activate_port_or_children_connections(NMPolicy *self, NMDevice *device, gboolean activate_children_connections_only) @@ -2286,9 +2227,8 @@ device_state_changed(NMDevice *device, NMPolicyPrivate *priv = user_data; NMPolicy *self = _PRIV_TO_SELF(priv); NMActiveConnection *ac; - NMSettingsConnection *sett_conn = nm_device_get_settings_connection(device); - NMSettingConnection *s_con = NULL; - gboolean is_activated_shared_device = FALSE; + NMSettingsConnection *sett_conn = nm_device_get_settings_connection(device); + NMSettingConnection *s_con = NULL; switch (nm_device_state_reason_check(reason)) { case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED: @@ -2404,10 +2344,6 @@ device_state_changed(NMDevice *device, } } } - if (!nm_device_get_refresh_forwarding_done(device)) { - refresh_forwarding(self, device, FALSE); - nm_device_set_refresh_forwarding_done(device, TRUE); - } break; case NM_DEVICE_STATE_ACTIVATED: if (nm_device_get_device_type(device) == NM_DEVICE_TYPE_OVS_INTERFACE) { @@ -2440,20 +2376,11 @@ device_state_changed(NMDevice *device, update_system_hostname(self, "routing and dns", TRUE); nm_dns_manager_end_updates(priv->dns_manager, __func__); - is_activated_shared_device = - nm_streq0(nm_device_get_effective_ip_config_method(device, AF_INET), - NM_SETTING_IP4_CONFIG_METHOD_SHARED); - refresh_forwarding(self, device, is_activated_shared_device); - nm_device_set_refresh_forwarding_done(device, FALSE); break; case NM_DEVICE_STATE_UNMANAGED: case NM_DEVICE_STATE_UNAVAILABLE: if (old_state > NM_DEVICE_STATE_DISCONNECTED) update_routing_and_dns(self, FALSE, device); - if (!nm_device_get_refresh_forwarding_done(device)) { - refresh_forwarding(self, device, FALSE); - nm_device_set_refresh_forwarding_done(device, TRUE); - } break; case NM_DEVICE_STATE_DEACTIVATING: if (sett_conn) { @@ -2489,10 +2416,6 @@ device_state_changed(NMDevice *device, } } ip6_remove_device_prefix_delegations(self, device); - if (!nm_device_get_refresh_forwarding_done(device)) { - refresh_forwarding(self, device, FALSE); - nm_device_set_refresh_forwarding_done(device, TRUE); - } break; case NM_DEVICE_STATE_DISCONNECTED: g_signal_handlers_disconnect_by_func(device, device_dns_lookup_done, self); @@ -2509,10 +2432,6 @@ device_state_changed(NMDevice *device, /* Device is now available for auto-activation */ nm_policy_device_recheck_auto_activate_schedule(self, device); - if (!nm_device_get_refresh_forwarding_done(device)) { - refresh_forwarding(self, device, FALSE); - nm_device_set_refresh_forwarding_done(device, TRUE); - } break; case NM_DEVICE_STATE_PREPARE: @@ -2528,10 +2447,6 @@ device_state_changed(NMDevice *device, g_object_weak_unref(G_OBJECT(ac), pending_ac_gone, self); g_object_unref(self); } - if (!nm_device_get_refresh_forwarding_done(device)) { - refresh_forwarding(self, device, FALSE); - nm_device_set_refresh_forwarding_done(device, TRUE); - } break; case NM_DEVICE_STATE_IP_CONFIG: /* We must have secrets if we got here. */ @@ -2542,10 +2457,6 @@ device_state_changed(NMDevice *device, sett_conn, NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED, FALSE); - if (!nm_device_get_refresh_forwarding_done(device)) { - refresh_forwarding(self, device, FALSE); - nm_device_set_refresh_forwarding_done(device, TRUE); - } break; case NM_DEVICE_STATE_SECONDARIES: if (sett_conn) diff --git a/src/libnm-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver index ad05a4e2..040d6829 100644 --- a/src/libnm-client-impl/libnm.ver +++ b/src/libnm-client-impl/libnm.ver @@ -2076,3 +2076,10 @@ global: nm_setting_sriov_get_preserve_on_down; nm_sriov_preserve_on_down_get_type; } libnm_1_52_0; + +libnm_1_54_2 { +global: + nm_setting_hsr_get_interlink; + nm_setting_hsr_get_protocol_version; + nm_setting_hsr_protocol_version_get_type; +} libnm_1_54_0; diff --git a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in index c764f535..ce4832dc 100644 --- a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in +++ b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in @@ -1516,6 +1516,10 @@ <setting name="hsr" gtype="NMSettingHsr" > + <property name="interlink" + dbus-type="s" + gprop-type="gchararray" + /> <property name="multicast-spec" dbus-type="u" gprop-type="guint" @@ -1528,6 +1532,10 @@ dbus-type="s" gprop-type="gchararray" /> + <property name="protocol-version" + dbus-type="i" + gprop-type="gint" + /> <property name="prp" dbus-type="b" gprop-type="gboolean" diff --git a/src/libnm-core-impl/nm-setting-hsr.c b/src/libnm-core-impl/nm-setting-hsr.c index d9a662b1..1edf4a14 100644 --- a/src/libnm-core-impl/nm-setting-hsr.c +++ b/src/libnm-core-impl/nm-setting-hsr.c @@ -23,12 +23,20 @@ /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE(NMSettingHsr, PROP_PORT1, PROP_PORT2, PROP_MULTICAST_SPEC, PROP_PRP, ); +NM_GOBJECT_PROPERTIES_DEFINE(NMSettingHsr, + PROP_PORT1, + PROP_PORT2, + PROP_MULTICAST_SPEC, + PROP_PRP, + PROP_PROTOCOL_VERSION, + PROP_INTERLINK, ); typedef struct { char *port1; char *port2; + char *interlink; guint32 multicast_spec; + int protocol_version; bool prp; } NMSettingHsrPrivate; @@ -117,6 +125,38 @@ nm_setting_hsr_get_prp(NMSettingHsr *setting) return NM_SETTING_HSR_GET_PRIVATE(setting)->prp; } +/** + * nm_setting_hsr_get_protocol_version: + * @setting: the #NMSettingHsr + * + * Returns: the #NMSettingHsr:protocol-version property of the setting + * + * Since: 1.56, 1.54.2 + **/ +NMSettingHsrProtocolVersion +nm_setting_hsr_get_protocol_version(NMSettingHsr *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_HSR(setting), NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT); + + return NM_SETTING_HSR_GET_PRIVATE(setting)->protocol_version; +} + +/** + * nm_setting_hsr_get_interlink: + * @setting: the #NMSettingHsr + * + * Returns: the #NMSettingHsr:interlink property of the setting + * + * Since: 1.56, 1.54.2 + **/ +const char * +nm_setting_hsr_get_interlink(NMSettingHsr *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_HSR(setting), NULL); + + return NM_SETTING_HSR_GET_PRIVATE(setting)->interlink; +} + /*****************************************************************************/ static gboolean @@ -160,6 +200,18 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } + if (priv->prp && priv->protocol_version != NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("HSR protocol cannot be configured for PRP interfaces")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_HSR_SETTING_NAME, + NM_SETTING_HSR_PROTOCOL_VERSION); + return FALSE; + } + return TRUE; } @@ -260,6 +312,42 @@ nm_setting_hsr_class_init(NMSettingHsrClass *klass) NMSettingHsr, _priv.prp); + /** + * NMSettingHsr:protocol-version: + * + * Configures the protocol version to be used for the HSR/PRP interface. + * %NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT sets the protocol version to the default version for the protocol. + * %NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2010 sets the protocol version to HSRv0 (IEC 62439-3:2010). + * %NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2012 sets the protocol version to HSRv1 (IEC 62439-3:2012). + * + * Since: 1.56, 1.54.2 + **/ + _nm_setting_property_define_direct_enum(properties_override, + obj_properties, + NM_SETTING_HSR_PROTOCOL_VERSION, + PROP_PROTOCOL_VERSION, + NM_TYPE_SETTING_HSR_PROTOCOL_VERSION, + NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT, + NM_SETTING_PARAM_NONE, + NULL, + NMSettingHsr, + _priv.protocol_version); + + /** + * NMSettingHsr:interlink: + * + * The optional interlink port name of the HSR interface. + * + * Since: 1.56, 1.54.2 + **/ + _nm_setting_property_define_direct_string(properties_override, + obj_properties, + NM_SETTING_HSR_INTERLINK, + PROP_INTERLINK, + NM_SETTING_PARAM_INFERRABLE, + NMSettingHsr, + _priv.interlink); + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_HSR, NULL, properties_override, 0); diff --git a/src/libnm-core-public/nm-dbus-interface.h b/src/libnm-core-public/nm-dbus-interface.h index 78241193..e62d64e1 100644 --- a/src/libnm-core-public/nm-dbus-interface.h +++ b/src/libnm-core-public/nm-dbus-interface.h @@ -145,8 +145,10 @@ typedef enum { * and not disable controls that require network access. * The graphical shells may hide the network accessibility indicator altogether * since no meaningful status indication can be provided. - * @NM_STATE_ASLEEP: Networking is not enabled, the system is being suspended or - * resumed from suspend. + * @NM_STATE_ASLEEP: Deprecated: 1.56: Use %NM_STATE_DISABLED instead. + * @NM_STATE_DISABLED: NetworkManager is disabled, either because the user requested + * to disable networking or because the system is suspended or resuming from suspend. + * Since: 1.56. * @NM_STATE_DISCONNECTED: There is no active network connection. * The graphical shell should indicate no network connectivity and the * applications should not attempt to access the network. @@ -170,7 +172,8 @@ typedef enum { **/ typedef enum { NM_STATE_UNKNOWN = 0, - NM_STATE_ASLEEP = 10, + NM_STATE_ASLEEP = 10, /* Deprecated */ + NM_STATE_DISABLED = 10, NM_STATE_DISCONNECTED = 20, NM_STATE_DISCONNECTING = 30, NM_STATE_CONNECTING = 40, @@ -632,8 +635,10 @@ typedef enum { * not initialized by udev. Since: 1.48 * @NM_DEVICE_STATE_REASON_UNMANAGED_QUITTING: The device is unmanaged because NetworkManager is * quitting. Since: 1.48 - * @NM_DEVICE_STATE_REASON_UNMANAGED_SLEEPING: The device is unmanaged because networking is - * disabled or the system is suspended. Since: 1.48 + * @NM_DEVICE_STATE_REASON_UNMANAGED_SLEEPING: Since: 1.48. Deprecated: 1.56: Use + * %NM_DEVICE_STATE_REASON_UNMANAGED_MANAGER_DISABLED instead. + * @NM_DEVICE_STATE_REASON_UNMANAGED_MANAGER_DISABLED: The device is unmanaged because networking is + * disabled or the system is suspended. Since: 1.56 * @NM_DEVICE_STATE_REASON_UNMANAGED_USER_CONF: The device is unmanaged by user decision in * NetworkManager.conf ('unmanaged' in a [device*] section). Since: 1.48 * @NM_DEVICE_STATE_REASON_UNMANAGED_USER_EXPLICIT: The device is unmanaged by explicit user @@ -642,7 +647,7 @@ typedef enum { * via settings plugin ('unmanaged-devices' for keyfile or 'NM_CONTROLLED=no' for ifcfg-rh). * Since: 1.48 * @NM_DEVICE_STATE_REASON_UNMANAGED_USER_UDEV: The device is unmanaged via udev rule. Since: 1.48 - + * @NM_DEVICE_STATE_REASON_NETWORKING_OFF: NetworkManager was disabled (networking off). Since: 1.56 * * Device state change reason codes */ @@ -720,11 +725,13 @@ typedef enum { NM_DEVICE_STATE_REASON_UNMANAGED_EXTERNAL_DOWN = 70, NM_DEVICE_STATE_REASON_UNMANAGED_LINK_NOT_INIT = 71, NM_DEVICE_STATE_REASON_UNMANAGED_QUITTING = 72, - NM_DEVICE_STATE_REASON_UNMANAGED_SLEEPING = 73, + NM_DEVICE_STATE_REASON_UNMANAGED_SLEEPING = 73, /* Deprecated */ + NM_DEVICE_STATE_REASON_UNMANAGED_MANAGER_DISABLED = 73, NM_DEVICE_STATE_REASON_UNMANAGED_USER_CONF = 74, NM_DEVICE_STATE_REASON_UNMANAGED_USER_EXPLICIT = 75, NM_DEVICE_STATE_REASON_UNMANAGED_USER_SETTINGS = 76, NM_DEVICE_STATE_REASON_UNMANAGED_USER_UDEV = 77, + NM_DEVICE_STATE_REASON_NETWORKING_OFF = 78, } NMDeviceStateReason; /** diff --git a/src/libnm-core-public/nm-setting-hsr.h b/src/libnm-core-public/nm-setting-hsr.h index f7b0136f..414f2b34 100644 --- a/src/libnm-core-public/nm-setting-hsr.h +++ b/src/libnm-core-public/nm-setting-hsr.h @@ -23,10 +23,28 @@ G_BEGIN_DECLS #define NM_SETTING_HSR_SETTING_NAME "hsr" -#define NM_SETTING_HSR_PORT1 "port1" -#define NM_SETTING_HSR_PORT2 "port2" -#define NM_SETTING_HSR_MULTICAST_SPEC "multicast-spec" -#define NM_SETTING_HSR_PRP "prp" +#define NM_SETTING_HSR_PORT1 "port1" +#define NM_SETTING_HSR_PORT2 "port2" +#define NM_SETTING_HSR_MULTICAST_SPEC "multicast-spec" +#define NM_SETTING_HSR_PRP "prp" +#define NM_SETTING_HSR_PROTOCOL_VERSION "protocol-version" +#define NM_SETTING_HSR_INTERLINK "interlink" + +/** + * NMSettingHsrProtocolVersion: + * @NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT: Default version for the protocol + * @NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2010: HSRv0, IEC 62439-3:2010 + * @NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2012: HSRv1, IEC 62439-3:2012 + * + * #NMSettingHsrProtocolVersion values indicate the HSR protocol version. + * + * Since: 1.56, 1.54.2 + */ +typedef enum { + NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT = -1, + NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2010 = 0, + NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2012 = 1, +} NMSettingHsrProtocolVersion; typedef struct _NMSettingHsrClass NMSettingHsrClass; @@ -43,6 +61,10 @@ NM_AVAILABLE_IN_1_46 guint32 nm_setting_hsr_get_multicast_spec(NMSettingHsr *setting); NM_AVAILABLE_IN_1_46 gboolean nm_setting_hsr_get_prp(NMSettingHsr *setting); +NM_AVAILABLE_IN_1_54_2 +NMSettingHsrProtocolVersion nm_setting_hsr_get_protocol_version(NMSettingHsr *setting); +NM_AVAILABLE_IN_1_54_2 +const char *nm_setting_hsr_get_interlink(NMSettingHsr *setting); G_END_DECLS diff --git a/src/libnm-core-public/nm-version-macros.h.in b/src/libnm-core-public/nm-version-macros.h.in index 4c4772d2..4bdf6716 100644 --- a/src/libnm-core-public/nm-version-macros.h.in +++ b/src/libnm-core-public/nm-version-macros.h.in @@ -78,6 +78,7 @@ #define NM_VERSION_1_50 (NM_ENCODE_VERSION(1, 50, 0)) #define NM_VERSION_1_52 (NM_ENCODE_VERSION(1, 52, 0)) #define NM_VERSION_1_54 (NM_ENCODE_VERSION(1, 54, 0)) +#define NM_VERSION_1_54_2 (NM_ENCODE_VERSION(1, 54, 2)) /* For releases, NM_API_VERSION is equal to NM_VERSION. * diff --git a/src/libnm-core-public/nm-version.h b/src/libnm-core-public/nm-version.h index 33daf65f..f8f49df2 100644 --- a/src/libnm-core-public/nm-version.h +++ b/src/libnm-core-public/nm-version.h @@ -439,6 +439,12 @@ #define NM_AVAILABLE_IN_1_54 #endif +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_54_2 +#define NM_AVAILABLE_IN_1_54_2 G_UNAVAILABLE(1, 54.2) +#else +#define NM_AVAILABLE_IN_1_54_2 +#endif + /* * Synchronous API for calling D-Bus in libnm is deprecated. See * https://networkmanager.dev/docs/libnm/latest/usage.html#sync-api diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index d45893fe..0c1097c2 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -253,7 +253,8 @@ G_STATIC_ASSERT(RTA_MAX == (__RTA_MAX - 1)); #define IFLA_HSR_SEQ_NR 5 #define IFLA_HSR_VERSION 6 #define IFLA_HSR_PROTOCOL 7 -#define __IFLA_HSR_MAX 8 +#define IFLA_HSR_INTERLINK 8 +#define __IFLA_HSR_MAX 9 /*****************************************************************************/ @@ -5196,6 +5197,15 @@ _nl_msg_new_link_set_linkinfo(struct nl_msg *msg, NMLinkType link_type, gconstpo NLA_PUT_U8(msg, IFLA_HSR_MULTICAST_SPEC, props->multicast_spec); NLA_PUT_U8(msg, IFLA_HSR_PROTOCOL, props->prp); + + if (!props->prp && props->protocol_version >= 0) { + NLA_PUT_U8(msg, IFLA_HSR_VERSION, props->protocol_version); + } + + if (props->interlink > 0) { + NLA_PUT_U32(msg, IFLA_HSR_INTERLINK, props->interlink); + } + break; } case NM_LINK_TYPE_SIT: diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c index fd966d2c..33c763c3 100644 --- a/src/libnm-platform/nm-platform.c +++ b/src/libnm-platform/nm-platform.c @@ -6560,6 +6560,8 @@ nm_platform_lnk_gre_to_string(const NMPlatformLnkGre *lnk, char *buf, gsize len) const char * nm_platform_lnk_hsr_to_string(const NMPlatformLnkHsr *lnk, char *buf, gsize len) { + char interlink_buf[30]; + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) return buf; @@ -6569,12 +6571,17 @@ nm_platform_lnk_hsr_to_string(const NMPlatformLnkHsr *lnk, char *buf, gsize len) "port1 %d " "port2 %d " "supervision_address " NM_ETHER_ADDR_FORMAT_STR " multicast_spec %u " - "prp %s", + "prp %s " + "protocol_version %d" + "%s", /* interlink */ lnk->port1, lnk->port2, NM_ETHER_ADDR_FORMAT_VAL(&lnk->supervision_address), lnk->multicast_spec, - lnk->prp ? "on" : "off"); + lnk->prp ? "on" : "off", + lnk->protocol_version, + lnk->interlink ? nm_sprintf_buf(interlink_buf, " interlink %d", lnk->interlink) + : ""); return buf; } @@ -8488,7 +8495,9 @@ nm_platform_lnk_hsr_hash_update(const NMPlatformLnkHsr *obj, NMHashState *h) obj->port2, obj->supervision_address, obj->multicast_spec, - NM_HASH_COMBINE_BOOLS(guint8, obj->prp)); + NM_HASH_COMBINE_BOOLS(guint8, obj->prp), + obj->protocol_version, + obj->interlink); } int @@ -8500,6 +8509,8 @@ nm_platform_lnk_hsr_cmp(const NMPlatformLnkHsr *a, const NMPlatformLnkHsr *b) NM_CMP_FIELD_MEMCMP(a, b, supervision_address); NM_CMP_FIELD(a, b, multicast_spec); NM_CMP_FIELD_BOOL(a, b, prp); + NM_CMP_FIELD(a, b, protocol_version); + NM_CMP_FIELD(a, b, interlink); return 0; } diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h index e4ccb9b1..a63f40c7 100644 --- a/src/libnm-platform/nm-platform.h +++ b/src/libnm-platform/nm-platform.h @@ -845,7 +845,9 @@ typedef struct { typedef struct { int port1; int port2; + int interlink; NMEtherAddr supervision_address; + gint8 protocol_version; guint8 multicast_spec; bool prp : 1; } _nm_alignas(NMPlatformObject) NMPlatformLnkHsr; diff --git a/src/libnmc-base/nm-client-utils.c b/src/libnmc-base/nm-client-utils.c index 0c4d53a4..326d8d20 100644 --- a/src/libnmc-base/nm-client-utils.c +++ b/src/libnmc-base/nm-client-utils.c @@ -467,7 +467,7 @@ NM_UTILS_LOOKUP_STR_DEFINE( N_("The Wi-Fi P2P peer could not be found")), NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_DEVICE_HANDLER_FAILED, N_("The device handler dispatcher returned an error")), - NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_SLEEPING, + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_MANAGER_DISABLED, N_("The device is unmanaged because networking is disabled " "or the system is suspended")), NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_QUITTING, @@ -492,6 +492,7 @@ NM_UTILS_LOOKUP_STR_DEFINE( NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_EXTERNAL_DOWN, N_("The device is unmanaged because it is an external device and is " "unconfigured (down or without addresses)")), + NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_NETWORKING_OFF, N_("Networking was disabled")), ); diff --git a/src/libnmc-setting/nm-meta-setting-desc.c b/src/libnmc-setting/nm-meta-setting-desc.c index aa290b9f..c035ad54 100644 --- a/src/libnmc-setting/nm-meta-setting-desc.c +++ b/src/libnmc-setting/nm-meta-setting-desc.c @@ -6198,6 +6198,12 @@ static const NMMetaPropertyInfo *const property_infos_HSR[] = { PROPERTY_INFO_WITH_DESC (NM_SETTING_HSR_PRP, .property_type = &_pt_gobject_bool, ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_HSR_PROTOCOL_VERSION, + .property_type = &_pt_gobject_enum, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_HSR_INTERLINK, + .property_type = &_pt_gobject_string, + ), NULL }; diff --git a/src/libnmc-setting/nm-meta-setting-desc.h b/src/libnmc-setting/nm-meta-setting-desc.h index 0294b1f7..9efbd15c 100644 --- a/src/libnmc-setting/nm-meta-setting-desc.h +++ b/src/libnmc-setting/nm-meta-setting-desc.h @@ -116,7 +116,8 @@ typedef enum { NM_META_COLOR_PERMISSION_UNKNOWN, NM_META_COLOR_PERMISSION_YES, NM_META_COLOR_PROMPT, - NM_META_COLOR_STATE_ASLEEP, + NM_META_COLOR_STATE_DISABLED, + NM_META_COLOR_STATE_ASLEEP = NM_META_COLOR_STATE_DISABLED, /* Deprecated */ NM_META_COLOR_STATE_CONNECTED_GLOBAL, NM_META_COLOR_STATE_CONNECTED_LOCAL, NM_META_COLOR_STATE_CONNECTED_SITE, diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in index 56c7c29c..ce9f27f9 100644 --- a/src/libnmc-setting/settings-docs.h.in +++ b/src/libnmc-setting/settings-docs.h.in @@ -171,9 +171,11 @@ #define DESCRIBE_DOC_NM_SETTING_GSM_SIM_ID N_("The SIM card unique identifier (as given by the WWAN management service) which this connection applies to. If given, the connection will apply to any device also allowed by \"device-id\" which contains a SIM card matching the given identifier.") #define DESCRIBE_DOC_NM_SETTING_GSM_SIM_OPERATOR_ID N_("A MCC/MNC string like \"310260\" or \"21601\" identifying the specific mobile network operator which this connection applies to. If given, the connection will apply to any device also allowed by \"device-id\" and \"sim-id\" which contains a SIM card provisioned by the given operator.") #define DESCRIBE_DOC_NM_SETTING_GSM_USERNAME N_("The username used to authenticate with the network, if required. Many providers do not require a username, or accept any username. But if a username is required, it is specified here.") +#define DESCRIBE_DOC_NM_SETTING_HSR_INTERLINK N_("The optional interlink port name of the HSR interface.") #define DESCRIBE_DOC_NM_SETTING_HSR_MULTICAST_SPEC N_("The last byte of supervision address.") #define DESCRIBE_DOC_NM_SETTING_HSR_PORT1 N_("The port1 interface name of the HSR. This property is mandatory.") #define DESCRIBE_DOC_NM_SETTING_HSR_PORT2 N_("The port2 interface name of the HSR. This property is mandatory.") +#define DESCRIBE_DOC_NM_SETTING_HSR_PROTOCOL_VERSION N_("Configures the protocol version to be used for the HSR/PRP interface. \"default\" (-1) sets the protocol version to the default version for the protocol. \"hsr-2010\" (0) sets the protocol version to HSRv0 (IEC 62439-3:2010). \"hsr-2012\" (1) sets the protocol version to HSRv1 (IEC 62439-3:2012).") #define DESCRIBE_DOC_NM_SETTING_HSR_PRP N_("The protocol used by the interface, whether it is PRP or HSR.") #define DESCRIBE_DOC_NM_SETTING_INFINIBAND_MAC_ADDRESS N_("If specified, this connection will only apply to the IPoIB device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing).") #define DESCRIBE_DOC_NM_SETTING_INFINIBAND_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames.") diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in index 67b14d4c..854a0227 100644 --- a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in +++ b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in @@ -1235,6 +1235,13 @@ nmcli-description="The protocol used by the interface, whether it is PRP or HSR." format="boolean" values="true/yes/on, false/no/off" /> + <property name="protocol-version" + nmcli-description="Configures the protocol version to be used for the HSR/PRP interface. "default" (-1) sets the protocol version to the default version for the protocol. "hsr-2010" (0) sets the protocol version to HSRv0 (IEC 62439-3:2010). "hsr-2012" (1) sets the protocol version to HSRv1 (IEC 62439-3:2012)." + format="choice (NMSettingHsrProtocolVersion)" + values="default (-1), hsr-2010 (0), hsr-2012 (1)" /> + <property name="interlink" + nmcli-description="The optional interlink port name of the HSR interface." + format="string" /> </setting> <setting name="infiniband" > <property name="mac-address" diff --git a/src/nmcli/general.c b/src/nmcli/general.c index 2e9aad44..a2772ca3 100644 --- a/src/nmcli/general.c +++ b/src/nmcli/general.c @@ -28,7 +28,7 @@ static void permission_changed(GObject *gobject, GParamSpec *pspec, NmCli *nmc); static NM_UTILS_LOOKUP_STR_DEFINE(nm_state_to_string, NMState, NM_UTILS_LOOKUP_DEFAULT(N_("unknown")), - NM_UTILS_LOOKUP_ITEM(NM_STATE_ASLEEP, N_("asleep")), + NM_UTILS_LOOKUP_ITEM(NM_STATE_DISABLED, N_("network off")), NM_UTILS_LOOKUP_ITEM(NM_STATE_CONNECTING, N_("connecting")), NM_UTILS_LOOKUP_ITEM(NM_STATE_CONNECTED_LOCAL, N_("connected (local only)")), @@ -53,8 +53,8 @@ state_to_color(NMState state) return NM_META_COLOR_STATE_CONNECTED_GLOBAL; case NM_STATE_DISCONNECTING: return NM_META_COLOR_STATE_DISCONNECTING; - case NM_STATE_ASLEEP: - return NM_META_COLOR_STATE_ASLEEP; + case NM_STATE_DISABLED: + return NM_META_COLOR_STATE_DISABLED; case NM_STATE_DISCONNECTED: return NM_META_COLOR_STATE_DISCONNECTED; default: diff --git a/src/nmcli/nmcli.c b/src/nmcli/nmcli.c index cfe4c5f4..09e15db9 100644 --- a/src/nmcli/nmcli.c +++ b/src/nmcli/nmcli.c @@ -581,6 +581,7 @@ static NM_UTILS_STRING_TABLE_LOOKUP_DEFINE( {"permission-unknown", NM_META_COLOR_PERMISSION_UNKNOWN}, {"permission-yes", NM_META_COLOR_PERMISSION_YES}, {"prompt", NM_META_COLOR_PROMPT}, + {"state-disabled", NM_META_COLOR_STATE_DISABLED}, {"state-asleep", NM_META_COLOR_STATE_ASLEEP}, {"state-connected-global", NM_META_COLOR_STATE_CONNECTED_GLOBAL}, {"state-connected-local", NM_META_COLOR_STATE_CONNECTED_LOCAL}, |