diff options
| author | Michael Biebl <biebl@debian.org> | 2025-02-12 13:46:50 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2025-02-12 13:46:50 +0100 |
| commit | 8bdf070ff046f482f6eb5e2b15ebc216f5d1e3da (patch) | |
| tree | f706478d189d54c6532e8863d4b0d5ff5575af60 /src | |
| parent | 818258cf34b83fbc754633295e1052d4752d7b15 (diff) | |
New upstream version 1.51.90 upstream/1.51.90
Diffstat (limited to 'src')
417 files changed, 16494 insertions, 6217 deletions
diff --git a/src/contrib/nm-vpn-plugin-utils.c b/src/contrib/nm-vpn-plugin-utils.c index 32af40cf..a9407608 100644 --- a/src/contrib/nm-vpn-plugin-utils.c +++ b/src/contrib/nm-vpn-plugin-utils.c @@ -11,8 +11,47 @@ /*****************************************************************************/ +char * +nm_vpn_plugin_utils_get_editor_module_path(const char *module_name, GError **error) +{ + gs_free char *module_path = NULL; + gs_free char *dirname = NULL; + Dl_info plugin_info; + + g_return_val_if_fail(module_name, NULL); + g_return_val_if_fail(!error || !*error, NULL); + + /* + * Look for the editor from the same directory this plugin is in. + * Ideally, we'd get our .so name from the NMVpnEditorPlugin if it + * would just have a property with it... + */ + if (!dladdr(nm_vpn_plugin_utils_load_editor, &plugin_info)) { + /* Really a "can not happen" scenario. */ + g_set_error(error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_FAILED, + _("unable to get editor plugin name: %s"), + dlerror()); + } + + dirname = g_path_get_dirname(plugin_info.dli_fname); + module_path = g_build_filename(dirname, module_name, NULL); + + if (!g_file_test(module_path, G_FILE_TEST_EXISTS)) { + g_set_error(error, + G_FILE_ERROR, + G_FILE_ERROR_NOENT, + _("missing plugin file \"%s\""), + module_path); + return NULL; + } + + return g_steal_pointer(&module_path); +} + NMVpnEditor * -nm_vpn_plugin_utils_load_editor(const char *module_name, +nm_vpn_plugin_utils_load_editor(const char *module_path, const char *factory_name, NMVpnPluginUtilsEditorFactory editor_factory, NMVpnEditorPlugin *editor_plugin, @@ -21,48 +60,36 @@ nm_vpn_plugin_utils_load_editor(const char *module_name, GError **error) { + gs_free char *compat_module_path = NULL; static struct { gpointer factory; void *dl_module; - char *module_name; + char *module_path; char *factory_name; } cached = {0}; - NMVpnEditor *editor; - gs_free char *module_path = NULL; - gs_free char *dirname = NULL; - Dl_info plugin_info; + NMVpnEditor *editor; - g_return_val_if_fail(module_name, NULL); + g_return_val_if_fail(module_path, NULL); g_return_val_if_fail(factory_name && factory_name[0], NULL); g_return_val_if_fail(editor_factory, NULL); g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(editor_plugin), NULL); g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL); g_return_val_if_fail(!error || !*error, NULL); - if (!g_path_is_absolute(module_name)) { - /* - * Load an editor from the same directory this plugin is in. - * Ideally, we'd get our .so name from the NMVpnEditorPlugin if it - * would just have a property with it... - */ - if (!dladdr(nm_vpn_plugin_utils_load_editor, &plugin_info)) { - /* Really a "can not happen" scenario. */ - g_set_error(error, - NM_VPN_PLUGIN_ERROR, - NM_VPN_PLUGIN_ERROR_FAILED, - _("unable to get editor plugin name: %s"), - dlerror()); - } - - dirname = g_path_get_dirname(plugin_info.dli_fname); - module_path = g_build_filename(dirname, module_name, NULL); - } else { - module_path = g_strdup(module_name); + if (!g_path_is_absolute(module_path)) { + /* This presumably means the VPN plugin factory() didn't verify that the plugin is there. + * Now it might be too late to do so. */ + g_warning("VPN plugin bug: load_editor() argument not an absolute path. Continuing..."); + compat_module_path = nm_vpn_plugin_utils_get_editor_module_path(module_path, error); + if (compat_module_path == NULL) + return NULL; + else + module_path = compat_module_path; } - /* we really expect this function to be called with unchanging @module_name + /* we really expect this function to be called with unchanging @module_path * and @factory_name. And we only want to load the module once, hence it would - * be more complicated to accept changing @module_name/@factory_name arguments. + * be more complicated to accept changing @module_path/@factory_name arguments. * * The reason for only loading once is that due to glib types, we cannot create a * certain type-name more then once, so loading the same module or another version @@ -70,12 +97,12 @@ nm_vpn_plugin_utils_load_editor(const char *module_name, * name. * * Only support loading once, any future calls will reuse the handle. To simplify - * that, we enforce that the @factory_name and @module_name is the same. */ + * that, we enforce that the @factory_name and @module_path is the same. */ if (cached.factory) { g_return_val_if_fail(cached.dl_module, NULL); g_return_val_if_fail(cached.factory_name && nm_streq0(cached.factory_name, factory_name), NULL); - g_return_val_if_fail(cached.module_name && nm_streq0(cached.module_name, module_name), + g_return_val_if_fail(cached.module_path && nm_streq0(cached.module_path, module_path), NULL); } else { gpointer factory; @@ -83,14 +110,6 @@ nm_vpn_plugin_utils_load_editor(const char *module_name, dl_module = dlopen(module_path, RTLD_LAZY | RTLD_LOCAL); if (!dl_module) { - if (!g_file_test(module_path, G_FILE_TEST_EXISTS)) { - g_set_error(error, - G_FILE_ERROR, - G_FILE_ERROR_NOENT, - _("missing plugin file \"%s\""), - module_path); - return NULL; - } g_set_error(error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_FAILED, @@ -117,7 +136,7 @@ nm_vpn_plugin_utils_load_editor(const char *module_name, * Thus we just leak the dl_module handle indefinitely. */ cached.factory = factory; cached.dl_module = dl_module; - cached.module_name = g_strdup(module_name); + cached.module_path = g_strdup(module_path); cached.factory_name = g_strdup(factory_name); } diff --git a/src/contrib/nm-vpn-plugin-utils.h b/src/contrib/nm-vpn-plugin-utils.h index b27b7513..6a6ea0b9 100644 --- a/src/contrib/nm-vpn-plugin-utils.h +++ b/src/contrib/nm-vpn-plugin-utils.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* - * Copyright (C) 2016 Red Hat, Inc. + * Copyright (C) 2016,2024 Red Hat, Inc. */ #ifndef __NM_VPN_PLUGIN_UTILS_H__ @@ -14,7 +14,9 @@ typedef NMVpnEditor *(NMVpnPluginUtilsEditorFactory) (gpointer factory gpointer user_data, GError **error); -NMVpnEditor *nm_vpn_plugin_utils_load_editor(const char *module_name, +char *nm_vpn_plugin_utils_get_editor_module_path(const char *module_name, GError **error); + +NMVpnEditor *nm_vpn_plugin_utils_load_editor(const char *module_path, const char *factory_name, NMVpnPluginUtilsEditorFactory editor_factory, NMVpnEditorPlugin *editor_plugin, diff --git a/src/core/NetworkManagerUtils.c b/src/core/NetworkManagerUtils.c index 2f447146..6c9e2f3d 100644 --- a/src/core/NetworkManagerUtils.c +++ b/src/core/NetworkManagerUtils.c @@ -250,23 +250,19 @@ nm_utils_ppp_ip_methods_enabled(NMConnection *connection, /*****************************************************************************/ void -_nm_utils_complete_generic_with_params(NMPlatform *platform, - NMConnection *connection, - const char *ctype, - NMConnection *const *existing_connections, - const char *preferred_id, - const char *fallback_id_prefix, - const char *ifname_prefix, - const char *ifname, - ...) +nm_utils_complete_generic(NMPlatform *platform, + NMConnection *connection, + const char *ctype, + NMConnection *const *existing_connections, + const char *preferred_id, + const char *fallback_id_prefix, + const char *ifname_prefix, + const char *ifname) { NMSettingConnection *s_con; char *id; char *generated_ifname; gs_unref_hashtable GHashTable *parameters = NULL; - va_list ap; - const char *p_val; - const char *p_key; g_assert(fallback_id_prefix); g_return_if_fail(ifname_prefix == NULL || ifname == NULL); @@ -301,20 +297,22 @@ _nm_utils_complete_generic_with_params(NMPlatform *platform, g_free(generated_ifname); } - /* Normalize */ - va_start(ap, ifname); - while ((p_key = va_arg(ap, const char *))) { - p_val = va_arg(ap, const char *); - if (!p_val) { - if (parameters) - g_hash_table_remove(parameters, p_key); - continue; - } - if (!parameters) - parameters = g_hash_table_new(nm_str_hash, g_str_equal); - g_hash_table_insert(parameters, (char *) p_key, (char *) p_val); + if (nm_connection_get_setting_adsl(connection) || nm_connection_get_setting_cdma(connection) + || nm_connection_get_setting_olpc_mesh(connection) + || nm_connection_get_setting_pppoe(connection) + || nm_connection_get_setting_vpn(connection)) { + parameters = g_hash_table_new(nm_str_hash, g_str_equal); + g_hash_table_insert(parameters, + NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE); + } else { + parameters = NULL; } - va_end(ap); + + /* We ignore the result, because the caller validates the connection. + * The only reason we do a normalization attempt here is + * NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD. + * Could we perhaps, one day, get rid of it? */ nm_connection_normalize(connection, parameters, NULL, NULL); } @@ -967,7 +965,7 @@ nm_match_spec_device_data_init_from_device(struct _NMMatchSpecDeviceData *out_da nm_assert(out_data); if (!device) { - *out_data = (NMMatchSpecDeviceData){}; + *out_data = (NMMatchSpecDeviceData) {}; return out_data; } @@ -983,7 +981,7 @@ nm_match_spec_device_data_init_from_device(struct _NMMatchSpecDeviceData *out_da * * The returned data is only valid, until NMDevice gets modified again. */ - *out_data = (NMMatchSpecDeviceData){ + *out_data = (NMMatchSpecDeviceData) { .interface_name = nm_device_get_iface(device), .device_type = nm_device_get_type_description(device), .driver = nm_device_get_driver(device), @@ -1010,7 +1008,7 @@ nm_match_spec_device_data_init_from_platform(NMMatchSpecDeviceData *out_data, * It's still useful because of specs like "*" and "except:interface-name:eth0", * which match even in that case. */ - *out_data = (NMMatchSpecDeviceData){ + *out_data = (NMMatchSpecDeviceData) { .interface_name = pllink ? pllink->name : NULL, .device_type = match_device_type, .driver = pllink ? pllink->driver : NULL, @@ -1057,7 +1055,7 @@ nm_ip_routing_rule_to_platform(const NMIPRoutingRule *rule, NMPlatformRoutingRul uid_range_has = nm_ip_routing_rule_get_uid_range(rule, &uid_range_start, &uid_range_end); - *out_pl = (NMPlatformRoutingRule){ + *out_pl = (NMPlatformRoutingRule) { .addr_family = nm_ip_routing_rule_get_addr_family(rule), .flags = (nm_ip_routing_rule_get_invert(rule) ? FIB_RULE_INVERT : 0), .priority = nm_ip_routing_rule_get_priority(rule), @@ -1200,7 +1198,7 @@ nm_shutdown_wait_obj_register_full(gpointer watched_obj, * make sure to use the default context. */ handle = g_slice_new(NMShutdownWaitObjHandle); - *handle = (NMShutdownWaitObjHandle){ + *handle = (NMShutdownWaitObjHandle) { /* depending on @free_msg_reason, we take ownership of @msg_reason. * In either case, we just reference the string without cloning * it. */ diff --git a/src/core/NetworkManagerUtils.h b/src/core/NetworkManagerUtils.h index 7d8afe5a..01f5bdb0 100644 --- a/src/core/NetworkManagerUtils.h +++ b/src/core/NetworkManagerUtils.h @@ -23,60 +23,14 @@ void nm_utils_ppp_ip_methods_enabled(NMConnection *connection, gboolean *out_ip4_enabled, gboolean *out_ip6_enabled); -void _nm_utils_complete_generic_with_params(NMPlatform *platform, - NMConnection *connection, - const char *ctype, - NMConnection *const *existing_connections, - const char *preferred_id, - const char *fallback_id_prefix, - const char *ifname_prefix, - const char *ifname, - ...) G_GNUC_NULL_TERMINATED; - -#define nm_utils_complete_generic_with_params(platform, \ - connection, \ - ctype, \ - existing_connections, \ - preferred_id, \ - fallback_id_prefix, \ - ifname_prefix, \ - ifname, \ - ...) \ - _nm_utils_complete_generic_with_params(platform, \ - connection, \ - ctype, \ - existing_connections, \ - preferred_id, \ - fallback_id_prefix, \ - ifname_prefix, \ - ifname, \ - ##__VA_ARGS__, \ - NULL) - -static inline void -nm_utils_complete_generic(NMPlatform *platform, - NMConnection *connection, - const char *ctype, - NMConnection *const *existing_connections, - const char *preferred_id, - const char *fallback_id_prefix, - const char *ifname_prefix, - const char *ifname, - gboolean default_enable_ipv6) -{ - nm_utils_complete_generic_with_params(platform, - connection, - ctype, - existing_connections, - preferred_id, - fallback_id_prefix, - ifname_prefix, - ifname, - NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD, - default_enable_ipv6 - ? NM_SETTING_IP6_CONFIG_METHOD_AUTO - : NM_SETTING_IP6_CONFIG_METHOD_IGNORE); -} +void nm_utils_complete_generic(NMPlatform *platform, + NMConnection *connection, + const char *ctype, + NMConnection *const *existing_connections, + const char *preferred_id, + const char *fallback_id_prefix, + const char *ifname_prefix, + const char *ifname); typedef gboolean(NMUtilsMatchFilterFunc)(NMConnection *connection, gpointer user_data); diff --git a/src/core/devices/adsl/nm-device-adsl.c b/src/core/devices/adsl/nm-device-adsl.c index ba605077..a6dc6326 100644 --- a/src/core/devices/adsl/nm-device-adsl.c +++ b/src/core/devices/adsl/nm-device-adsl.c @@ -117,8 +117,7 @@ complete_connection(NMDevice *device, NULL, _("ADSL connection"), NULL, - NULL, - FALSE); /* No IPv6 yet by default */ + NULL); return TRUE; } @@ -494,7 +493,7 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) _LOGD(LOGD_ADSL, "starting PPPoA"); } - priv->ppp_mgr = nm_ppp_mgr_start(&((const NMPppMgrConfig){ + priv->ppp_mgr = nm_ppp_mgr_start(&((const NMPppMgrConfig) { .netns = nm_device_get_netns(device), .parent_iface = ppp_iface, .callback = _ppp_mgr_callback, diff --git a/src/core/devices/bluetooth/nm-bluez-manager.c b/src/core/devices/bluetooth/nm-bluez-manager.c index ac26ede8..3088cd6f 100644 --- a/src/core/devices/bluetooth/nm-bluez-manager.c +++ b/src/core/devices/bluetooth/nm-bluez-manager.c @@ -334,7 +334,7 @@ _bz_dbus_obj_new(NMBluezManager *self, const char *object_path) l = strlen(object_path) + 1; bzobj = g_malloc(sizeof(BzDBusObj) + l); - *bzobj = (BzDBusObj){ + *bzobj = (BzDBusObj) { .object_path = bzobj->_object_path_intern, .self = self, .x_network_server.lst = C_LIST_INIT(bzobj->x_network_server.lst), @@ -751,7 +751,7 @@ _conn_data_head_new(NMBluetoothCapabilities bt_type, const char *bdaddr) l = strlen(bdaddr) + 1; cdata_hd = g_malloc(sizeof(ConnDataHead) + l); - *cdata_hd = (ConnDataHead){ + *cdata_hd = (ConnDataHead) { .bdaddr = cdata_hd->bdaddr_data, .lst_head = C_LIST_INIT(cdata_hd->lst_head), .bt_type = bt_type, @@ -1143,7 +1143,7 @@ _network_server_vt_register_bridge(const NMBtVTableNetworkServer *vtable, bzobj->d_adapter.address); r_req_data = g_slice_new(NetworkServerRegisterReqData); - *r_req_data = (NetworkServerRegisterReqData){ + *r_req_data = (NetworkServerRegisterReqData) { .int_cancellable = g_cancellable_new(), .ext_cancellable = g_object_ref(cancellable), .callback = callback, @@ -2749,7 +2749,7 @@ nm_bluez_manager_connect(NMBluezManager *self, } c_req_data = g_slice_new(DeviceConnectReqData); - *c_req_data = (DeviceConnectReqData){ + *c_req_data = (DeviceConnectReqData) { .int_cancellable = g_steal_pointer(&int_cancellable), .ext_cancellable = g_object_ref(cancellable), .callback = callback, @@ -2814,7 +2814,7 @@ nm_bluez_manager_init(NMBluezManager *self) { NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE(self); - priv->vtable_network_server = (NMBtVTableNetworkServer){ + priv->vtable_network_server = (NMBtVTableNetworkServer) { .is_available = _network_server_vt_is_available, .register_bridge = _network_server_vt_register_bridge, .unregister_bridge = _network_server_vt_unregister_bridge, diff --git a/src/core/devices/bluetooth/nm-bluez5-dun.c b/src/core/devices/bluetooth/nm-bluez5-dun.c index 426bab0c..08d37c27 100644 --- a/src/core/devices/bluetooth/nm-bluez5-dun.c +++ b/src/core/devices/bluetooth/nm-bluez5-dun.c @@ -683,7 +683,7 @@ nm_bluez5_dun_connect(const char *adapter, dst_l = strlen(remote) + 1; cdat = g_slice_new(ConnectData); - *cdat = (ConnectData){ + *cdat = (ConnectData) { .callback = callback, .callback_user_data = callback_user_data, .cancellable = g_object_ref(cancellable), @@ -691,7 +691,7 @@ nm_bluez5_dun_connect(const char *adapter, }; context = g_malloc(sizeof(NMBluez5DunContext) + src_l + dst_l); - *context = (NMBluez5DunContext){ + *context = (NMBluez5DunContext) { .cdat = cdat, .notify_tty_hangup_cb = notify_tty_hangup_cb, .notify_tty_hangup_user_data = notify_tty_hangup_user_data, diff --git a/src/core/devices/bluetooth/nm-device-bt.c b/src/core/devices/bluetooth/nm-device-bt.c index ce110aa0..4406bcf4 100644 --- a/src/core/devices/bluetooth/nm-device-bt.c +++ b/src/core/devices/bluetooth/nm-device-bt.c @@ -404,8 +404,7 @@ complete_connection(NMDevice *device, preferred, fallback_prefix, NULL, - NULL, - is_dun ? FALSE : TRUE); /* No IPv6 yet for DUN */ + NULL); setting_bdaddr = nm_setting_bluetooth_get_bdaddr(s_bt); if (setting_bdaddr) { diff --git a/src/core/devices/nm-device-6lowpan.c b/src/core/devices/nm-device-6lowpan.c index 78ec634c..3dabcb9b 100644 --- a/src/core/devices/nm-device-6lowpan.c +++ b/src/core/devices/nm-device-6lowpan.c @@ -161,8 +161,7 @@ complete_connection(NMDevice *device, NULL, _("6LOWPAN connection"), NULL, - NULL, - TRUE); + NULL); s_6lowpan = NM_SETTING_6LOWPAN(nm_connection_get_setting(connection, NM_TYPE_SETTING_6LOWPAN)); if (!s_6lowpan) { @@ -276,27 +275,10 @@ get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_6LOWPAN_SETTING_NAME), NULL); s_6lowpan = NM_SETTING_6LOWPAN(nm_connection_get_setting(connection, NM_TYPE_SETTING_6LOWPAN)); - g_assert(s_6lowpan); - - return nm_setting_6lowpan_get_parent(s_6lowpan); -} - -static char * -get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const char *parent_iface) -{ - NMSetting6Lowpan *s_6lowpan; - const char *ifname; - - g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_6LOWPAN_SETTING_NAME), NULL); - - s_6lowpan = NM_SETTING_6LOWPAN(nm_connection_get_setting(connection, NM_TYPE_SETTING_6LOWPAN)); - g_assert(s_6lowpan); - - if (!parent_iface) + if (s_6lowpan) + return nm_setting_6lowpan_get_parent(s_6lowpan); + else return NULL; - - ifname = nm_connection_get_interface_name(connection); - return g_strdup(ifname); } NM_DEVICE_FACTORY_DEFINE_INTERNAL( @@ -306,5 +288,4 @@ NM_DEVICE_FACTORY_DEFINE_INTERNAL( NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_6LOWPAN) NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_6LOWPAN_SETTING_NAME), factory_class->create_device = create_device; - factory_class->get_connection_parent = get_connection_parent; - factory_class->get_connection_iface = get_connection_iface;); + factory_class->get_connection_parent = get_connection_parent;); diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c index 3ab17aff..53b32466 100644 --- a/src/core/devices/nm-device-bond.c +++ b/src/core/devices/nm-device-bond.c @@ -94,8 +94,7 @@ complete_connection(NMDevice *device, NULL, _("Bond connection"), "bond", - NULL, - TRUE); + NULL); _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_BOND); @@ -436,7 +435,7 @@ _platform_lnk_bond_init_from_setting(NMSettingBond *s_bond, NMPlatformLnkBond *p #define _v_u32(s_bond, opt) _nm_setting_bond_opt_value_as_u32((s_bond), (opt)) #define _v_intbool(s_bond, opt) _nm_setting_bond_opt_value_as_intbool((s_bond), (opt)) - *props = (NMPlatformLnkBond){ + *props = (NMPlatformLnkBond) { .mode = _v_fcn(_nm_setting_bond_mode_from_string, s_bond, NM_SETTING_BOND_OPTION_MODE), .primary = _setting_bond_primary_opt_as_ifindex(s_bond), .miimon = _v_u32(s_bond, NM_SETTING_BOND_OPTION_MIIMON), @@ -681,7 +680,7 @@ commit_port_options(NMDevice *bond_device, NMDevice *port, NMSettingBondPort *s_ nm_platform_link_change(nm_device_get_platform(port), nm_device_get_ifindex(port), NULL, - &((NMPlatformLinkBondPort){ + &((NMPlatformLinkBondPort) { .queue_id = s_port ? nm_setting_bond_port_get_queue_id(s_port) : NM_BOND_PORT_QUEUE_ID_DEF, .prio = prio_has ? prio : 0, diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c index a237c0b7..7c34fde0 100644 --- a/src/core/devices/nm-device-bridge.c +++ b/src/core/devices/nm-device-bridge.c @@ -164,8 +164,7 @@ complete_connection(NMDevice *device, NULL, _("Bridge connection"), "bridge", - NULL, - TRUE); + NULL); _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_BRIDGE); @@ -439,7 +438,7 @@ setting_vlans_to_platform(GPtrArray *array, guint *out_len) nm_bridge_vlan_get_vid_range(vlan, &vid_start, &vid_end); - arr[i] = (NMPlatformBridgeVlan){ + arr[i] = (NMPlatformBridgeVlan) { .vid_start = vid_start, .vid_end = vid_end, .pvid = nm_bridge_vlan_is_pvid(vlan), @@ -468,7 +467,7 @@ commit_port_options(NMDevice *device, NMSettingBridgePort *setting) nm_device_get_ifindex(device), NULL, NULL, - &((NMPlatformLinkBridgePort){ + &((NMPlatformLinkBridgePort) { .path_cost = path_cost, .priority = priority, .hairpin = nm_setting_bridge_port_get_hairpin_mode(setting), @@ -660,10 +659,10 @@ bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge, gboolean is 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 = 1})); + &((NMPlatformLinkSetBridgeInfoData) {.vlan_filtering_has = TRUE, + .vlan_filtering_val = FALSE, + .vlan_default_pvid_has = TRUE, + .vlan_default_pvid_val = 1})); nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, NULL, 0); return TRUE; } @@ -690,10 +689,10 @@ bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge, gboolean is 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})); + &((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, 0)) @@ -706,8 +705,8 @@ bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge, gboolean is nm_platform_link_set_bridge_info( plat, ifindex, - &((NMPlatformLinkSetBridgeInfoData){.vlan_default_pvid_has = TRUE, - .vlan_default_pvid_val = pvid})); + &((NMPlatformLinkSetBridgeInfoData) {.vlan_default_pvid_has = TRUE, + .vlan_default_pvid_val = pvid})); } } @@ -721,7 +720,7 @@ bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge, gboolean is nm_platform_link_set_bridge_info(plat, ifindex, - &((NMPlatformLinkSetBridgeInfoData){ + &((NMPlatformLinkSetBridgeInfoData) { .vlan_filtering_has = TRUE, .vlan_filtering_val = TRUE, })); @@ -757,7 +756,7 @@ merge_bridge_vlan_default_pvid(NMPlatformBridgeVlan *vlans, guint *num_vlans, gu * Set the PVID flag only if the port didn't have one. */ vlans = g_realloc_n(vlans, *num_vlans + 1, sizeof(NMPlatformBridgeVlan)); (*num_vlans)++; - vlans[*num_vlans - 1] = (NMPlatformBridgeVlan){ + vlans[*num_vlans - 1] = (NMPlatformBridgeVlan) { .vid_start = default_pvid, .vid_end = default_pvid, .untagged = TRUE, @@ -847,7 +846,7 @@ nm_device_reapply_bridge_port_vlans(NMDevice *device) static void _platform_lnk_bridge_init_from_setting(NMSettingBridge *s_bridge, NMPlatformLnkBridge *props) { - *props = (NMPlatformLnkBridge){ + *props = (NMPlatformLnkBridge) { .forward_delay = _DEFAULT_IF_ZERO(nm_setting_bridge_get_forward_delay(s_bridge) * 100u, NM_BRIDGE_FORWARD_DELAY_DEF_SYS), .hello_time = _DEFAULT_IF_ZERO(nm_setting_bridge_get_hello_time(s_bridge) * 100u, diff --git a/src/core/devices/nm-device-dummy.c b/src/core/devices/nm-device-dummy.c index b7c4106a..1bc5447f 100644 --- a/src/core/devices/nm-device-dummy.c +++ b/src/core/devices/nm-device-dummy.c @@ -48,14 +48,14 @@ complete_connection(NMDevice *device, NMConnection *const *existing_connections, GError **error) { - nm_utils_complete_generic_with_params(nm_device_get_platform(device), - connection, - NM_SETTING_DUMMY_SETTING_NAME, - existing_connections, - NULL, - _("Dummy connection"), - NULL, - nm_device_get_ip_iface(device)); + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_DUMMY_SETTING_NAME, + existing_connections, + NULL, + _("Dummy connection"), + NULL, + nm_device_get_ip_iface(device)); _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_DUMMY); diff --git a/src/core/devices/nm-device-ethernet.c b/src/core/devices/nm-device-ethernet.c index 16992524..4034fdaa 100644 --- a/src/core/devices/nm-device-ethernet.c +++ b/src/core/devices/nm-device-ethernet.c @@ -1451,7 +1451,7 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) g_return_val_if_fail(s_pppoe, NM_ACT_STAGE_RETURN_FAILURE); priv->ppp_data.ppp_mgr = - nm_ppp_mgr_start(&((const NMPppMgrConfig){ + nm_ppp_mgr_start(&((const NMPppMgrConfig) { .netns = nm_device_get_netns(device), .parent_iface = nm_device_get_iface(device), .callback = _ppp_mgr_callback, @@ -1640,8 +1640,7 @@ complete_connection(NMDevice *device, NULL, _("Veth connection"), "veth", - NULL, - TRUE); + NULL); s_veth = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_VETH); @@ -1698,8 +1697,7 @@ complete_connection(NMDevice *device, NULL, s_pppoe ? _("PPPoE connection") : _("Wired connection"), NULL, - nm_setting_wired_get_mac_address(s_wired) ? NULL : nm_device_get_iface(device), - s_pppoe ? FALSE : TRUE); /* No IPv6 by default yet for PPPoE */ + nm_setting_wired_get_mac_address(s_wired) ? NULL : nm_device_get_iface(device)); return TRUE; } diff --git a/src/core/devices/nm-device-factory.c b/src/core/devices/nm-device-factory.c index 22c8fa5a..15858362 100644 --- a/src/core/devices/nm-device-factory.c +++ b/src/core/devices/nm-device-factory.c @@ -147,7 +147,7 @@ nm_device_factory_get_connection_iface(NMDeviceFactory *factory, g_set_error(error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, - "failed to determine interface name: error determine name for %s", + "failed to determine interface name for a %s", nm_connection_get_connection_type(connection)); return NULL; } @@ -415,6 +415,7 @@ nm_device_factory_manager_load_factories(NMDeviceFactoryManagerFactoryFunc callb _ADD_INTERNAL(nm_hsr_device_factory_get_type); _ADD_INTERNAL(nm_infiniband_device_factory_get_type); _ADD_INTERNAL(nm_ip_tunnel_device_factory_get_type); + _ADD_INTERNAL(nm_ipvlan_device_factory_get_type); _ADD_INTERNAL(nm_loopback_device_factory_get_type); _ADD_INTERNAL(nm_macsec_device_factory_get_type); _ADD_INTERNAL(nm_macvlan_device_factory_get_type); diff --git a/src/core/devices/nm-device-factory.h b/src/core/devices/nm-device-factory.h index 004ae9b1..d4aae75f 100644 --- a/src/core/devices/nm-device-factory.h +++ b/src/core/devices/nm-device-factory.h @@ -69,11 +69,15 @@ typedef struct { /** * get_connection_parent: * @factory: the #NMDeviceFactory - * @connection: the #NMConnection to return the parent name for, if supported + * @connection: the #NMConnection (possibly incomplete) to return the parent name for, if supported * * Given a connection, returns the parent interface name, parent connection * UUID, or parent device permanent hardware address for @connection. * + * Note that @connection is not necessarily a valid connection. + * It might be called during AddAndActivate before the connection is + * completed and normalized. + * * Returns: the parent interface name, parent connection UUID, parent * device permanent hardware address, or %NULL */ @@ -82,12 +86,16 @@ typedef struct { /** * get_connection_iface: * @factory: the #NMDeviceFactory - * @connection: the #NMConnection to return the interface name for + * @connection: the #NMConnection (possibly incomplete) to return the interface name for * @parent_iface: optional parent interface name for virtual devices * * Given a connection, returns the interface name that a device activating * that connection would have. * + * Note that @connection is not necessarily a valid connection. + * It might be called during AddAndActivate before the connection is + * completed and normalized. + * * Returns: the interface name, or %NULL */ char *(*get_connection_iface)(NMDeviceFactory *factory, diff --git a/src/core/devices/nm-device-infiniband.c b/src/core/devices/nm-device-infiniband.c index c974696c..a5a82b94 100644 --- a/src/core/devices/nm-device-infiniband.c +++ b/src/core/devices/nm-device-infiniband.c @@ -159,8 +159,7 @@ complete_connection(NMDevice *device, NULL, _("InfiniBand connection"), NULL, - nm_setting_infiniband_get_mac_address(s_infiniband) ? NULL : nm_device_get_iface(device), - TRUE); + nm_setting_infiniband_get_mac_address(s_infiniband) ? NULL : nm_device_get_iface(device)); if (!nm_setting_infiniband_get_transport_mode(s_infiniband)) g_object_set(G_OBJECT(s_infiniband), @@ -464,9 +463,10 @@ get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) NULL); s_infiniband = nm_connection_get_setting_infiniband(connection); - g_assert(s_infiniband); - - return nm_setting_infiniband_get_parent(s_infiniband); + if (s_infiniband) + return nm_setting_infiniband_get_parent(s_infiniband); + else + return NULL; } static char * @@ -477,17 +477,19 @@ get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const c g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_INFINIBAND_SETTING_NAME), NULL); - s_infiniband = nm_connection_get_setting_infiniband(connection); - g_assert(s_infiniband); - if (!parent_iface) return NULL; - g_return_val_if_fail(g_strcmp0(parent_iface, nm_setting_infiniband_get_parent(s_infiniband)) - == 0, - NULL); + s_infiniband = nm_connection_get_setting_infiniband(connection); + if (s_infiniband) { + g_return_val_if_fail(g_strcmp0(parent_iface, nm_setting_infiniband_get_parent(s_infiniband)) + == 0, + NULL); - return g_strdup(nm_setting_infiniband_get_virtual_interface_name(s_infiniband)); + return g_strdup(nm_setting_infiniband_get_virtual_interface_name(s_infiniband)); + } else { + return NULL; + } } NM_DEVICE_FACTORY_DEFINE_INTERNAL( diff --git a/src/core/devices/nm-device-ip-tunnel.c b/src/core/devices/nm-device-ip-tunnel.c index cc62180e..2ecfe453 100644 --- a/src/core/devices/nm-device-ip-tunnel.c +++ b/src/core/devices/nm-device-ip-tunnel.c @@ -402,8 +402,7 @@ complete_connection(NMDevice *device, NULL, _("IP tunnel connection"), NULL, - NULL, - TRUE); + NULL); s_ip_tunnel = nm_connection_get_setting_ip_tunnel(connection); if (!s_ip_tunnel) { @@ -1369,29 +1368,10 @@ get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) NULL); s_ip_tunnel = nm_connection_get_setting_ip_tunnel(connection); - g_assert(s_ip_tunnel); - - return nm_setting_ip_tunnel_get_parent(s_ip_tunnel); -} - -static char * -get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const char *parent_iface) -{ - const char *ifname; - NMSettingIPTunnel *s_ip_tunnel; - - g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_IP_TUNNEL_SETTING_NAME), - NULL); - - s_ip_tunnel = nm_connection_get_setting_ip_tunnel(connection); - g_assert(s_ip_tunnel); - - if (nm_setting_ip_tunnel_get_parent(s_ip_tunnel) && !parent_iface) + if (s_ip_tunnel) + return nm_setting_ip_tunnel_get_parent(s_ip_tunnel); + else return NULL; - - ifname = nm_connection_get_interface_name(connection); - - return g_strdup(ifname); } NM_DEVICE_FACTORY_DEFINE_INTERNAL( @@ -1409,5 +1389,4 @@ NM_DEVICE_FACTORY_DEFINE_INTERNAL( NM_LINK_TYPE_VTI6) NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_IP_TUNNEL_SETTING_NAME), factory_class->create_device = create_device; - factory_class->get_connection_parent = get_connection_parent; - factory_class->get_connection_iface = get_connection_iface;); + factory_class->get_connection_parent = get_connection_parent;); diff --git a/src/core/devices/nm-device-ipvlan.c b/src/core/devices/nm-device-ipvlan.c new file mode 100644 index 00000000..00a1b579 --- /dev/null +++ b/src/core/devices/nm-device-ipvlan.c @@ -0,0 +1,467 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024 Red Hat, Inc. + */ + +#include "src/core/nm-default-daemon.h" + +#include "nm-device-ipvlan.h" + +#include <linux/if_link.h> + +#include "libnm-core-intern/nm-core-internal.h" +#include "nm-device-private.h" +#include "settings/nm-settings.h" +#include "nm-act-request.h" +#include "nm-manager.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" +#include "libnm-platform/nm-platform.h" +#include "nm-device-factory.h" +#include "nm-setting-ipvlan.h" +#include "nm-setting-wired.h" +#include "nm-active-connection.h" +#include "nm-utils.h" + +#define _NMLOG_DEVICE_TYPE NMDeviceIpvlan +#include "nm-device-logging.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceIpvlan, PROP_MODE, PROP_PRIVATE, PROP_VEPA, ); + +typedef struct { + NMPlatformLnkIpvlan props; +} NMDeviceIpvlanPrivate; + +struct _NMDeviceIpvlan { + NMDevice parent; + NMDeviceIpvlanPrivate _priv; +}; + +struct _NMDeviceIpvlanClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceIpvlan, nm_device_ipvlan, NM_TYPE_DEVICE); + +#define NM_DEVICE_IPVLAN_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceIpvlan, NM_IS_DEVICE_IPVLAN, NMDevice) + +/*****************************************************************************/ + +static int modes[][2] = { + {NM_SETTING_IPVLAN_MODE_L2, IPVLAN_MODE_L2}, + {NM_SETTING_IPVLAN_MODE_L3, IPVLAN_MODE_L3}, + {NM_SETTING_IPVLAN_MODE_L3S, IPVLAN_MODE_L3S}, +}; + +static int +setting_mode_to_platform(int mode) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS(modes); i++) { + if (modes[i][0] == mode) + return modes[i][1]; + } + + return -1; +} + +static int +platform_mode_to_setting(int mode) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS(modes); i++) { + if (modes[i][1] == mode) + return modes[i][0]; + } + + return 0; +} + +static const char * +platform_mode_to_string(guint mode) +{ + switch (mode) { + case IPVLAN_MODE_L2: + return "l2"; + case IPVLAN_MODE_L3: + return "l3"; + case IPVLAN_MODE_L3S: + return "l3s"; + default: + return "unknown"; + } +} + +/*****************************************************************************/ + +static void +update_properties(NMDevice *device) +{ + NMDeviceIpvlan *self = NM_DEVICE_IPVLAN(device); + NMDeviceIpvlanPrivate *priv = NM_DEVICE_IPVLAN_GET_PRIVATE(self); + GObject *object = G_OBJECT(device); + const NMPlatformLnkIpvlan *props; + const NMPlatformLink *plink; + + props = nm_platform_link_get_lnk_ipvlan(nm_device_get_platform(device), + nm_device_get_ifindex(device), + &plink); + + if (!props) { + _LOGW(LOGD_PLATFORM, "could not get IPVLAN properties"); + return; + } + + g_object_freeze_notify(object); + + nm_device_parent_set_ifindex(device, plink->parent); + +#define CHECK_PROPERTY_CHANGED(field, prop) \ + G_STMT_START \ + { \ + if (priv->props.field != props->field) { \ + priv->props.field = props->field; \ + _notify(self, prop); \ + } \ + } \ + G_STMT_END + + CHECK_PROPERTY_CHANGED(mode, PROP_MODE); + CHECK_PROPERTY_CHANGED(private_flag, PROP_PRIVATE); + CHECK_PROPERTY_CHANGED(vepa, PROP_VEPA); + + g_object_thaw_notify(object); +} + +static void +link_changed(NMDevice *device, const NMPlatformLink *pllink) +{ + NM_DEVICE_CLASS(nm_device_ipvlan_parent_class)->link_changed(device, pllink); + update_properties(device); +} + +static gboolean +create_and_realize(NMDevice *device, + NMConnection *connection, + NMDevice *parent, + const NMPlatformLink **out_plink, + GError **error) +{ + const char *iface = nm_device_get_iface(device); + NMSettingIpvlan *s_ipvlan; + NMPlatformLnkIpvlan lnk = {}; + int parent_ifindex; + int r; + + s_ipvlan = _nm_connection_get_setting(connection, NM_TYPE_SETTING_IPVLAN); + nm_assert(s_ipvlan); + + if (!parent) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_MISSING_DEPENDENCIES, + "IPVLAN device cannot be created without a parent interface"); + return FALSE; + } + + parent_ifindex = nm_device_get_ifindex(parent); + if (parent_ifindex <= 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_MISSING_DEPENDENCIES, + "cannot retrieve ifindex of interface %s (%s)", + nm_device_get_iface(parent), + nm_device_get_type_desc(parent)); + return FALSE; + } + + if (setting_mode_to_platform(nm_setting_ipvlan_get_mode(s_ipvlan)) < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "unsupported IPVLAN mode %u", + nm_setting_ipvlan_get_mode(s_ipvlan)); + return FALSE; + } + lnk.mode = setting_mode_to_platform(nm_setting_ipvlan_get_mode(s_ipvlan)); + lnk.private_flag = nm_setting_ipvlan_get_private(s_ipvlan); + lnk.vepa = nm_setting_ipvlan_get_vepa(s_ipvlan); + + r = nm_platform_link_ipvlan_add(nm_device_get_platform(device), + iface, + parent_ifindex, + &lnk, + out_plink); + + if (r < 0) { + g_set_error(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_CREATION_FAILED, + "Failed to create IPVLAN interface '%s' for '%s': %s", + iface, + nm_connection_get_id(connection), + nm_strerror(r)); + return FALSE; + } + + return TRUE; +} + +/*****************************************************************************/ + +static NMDeviceCapabilities +get_generic_capabilities(NMDevice *device) +{ + return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; +} + +/*****************************************************************************/ + +static gboolean +is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags) +{ + if (!nm_device_parent_get_device(device)) + return FALSE; + return NM_DEVICE_CLASS(nm_device_ipvlan_parent_class)->is_available(device, flags); +} + +/*****************************************************************************/ + +static gboolean +check_connection_compatible(NMDevice *device, + NMConnection *connection, + gboolean check_properties, + GError **error) +{ + NMDeviceIpvlanPrivate *priv = NM_DEVICE_IPVLAN_GET_PRIVATE(device); + NMSettingIpvlan *s_ipvlan; + const char *parent = NULL; + + if (!NM_DEVICE_CLASS(nm_device_ipvlan_parent_class) + ->check_connection_compatible(device, connection, check_properties, error)) + return FALSE; + + s_ipvlan = _nm_connection_get_setting(connection, NM_TYPE_SETTING_IPVLAN); + + if (check_properties && nm_device_is_real(device)) { + if (setting_mode_to_platform(nm_setting_ipvlan_get_mode(s_ipvlan)) != priv->props.mode) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "IPVLAN mode setting differs"); + return FALSE; + } + + if (nm_setting_ipvlan_get_private(s_ipvlan) != priv->props.private_flag) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "IPVLAN private flag setting differs"); + return FALSE; + } + if (nm_setting_ipvlan_get_vepa(s_ipvlan) != priv->props.vepa) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "IPVLAN VEPA flag setting differs"); + return FALSE; + } + + /* Check parent interface; could be an interface name or a UUID */ + parent = nm_setting_ipvlan_get_parent(s_ipvlan); + if (parent) { + if (!nm_device_match_parent(device, parent)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "IPVLAN parent setting differs"); + return FALSE; + } + } else { + /* Parent could be a MAC address in an NMSettingWired */ + if (!nm_device_match_parent_hwaddr(device, connection, TRUE)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, + "IPVLAN parent mac setting differs"); + return FALSE; + } + } + } + return TRUE; +} + +static void +update_connection(NMDevice *device, NMConnection *connection) +{ + NMDeviceIpvlanPrivate *priv = NM_DEVICE_IPVLAN_GET_PRIVATE(device); + NMSettingIpvlan *s_ipvlan = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_IPVLAN); + + if (priv->props.mode != setting_mode_to_platform(nm_setting_ipvlan_get_mode(s_ipvlan))) + g_object_set(s_ipvlan, + NM_SETTING_IPVLAN_MODE, + platform_mode_to_setting(priv->props.mode), + NULL); + + if (priv->props.private_flag != nm_setting_ipvlan_get_private(s_ipvlan)) + g_object_set(s_ipvlan, NM_SETTING_IPVLAN_PRIVATE, priv->props.private_flag, NULL); + + if (priv->props.vepa != nm_setting_ipvlan_get_vepa(s_ipvlan)) + g_object_set(s_ipvlan, NM_SETTING_IPVLAN_VEPA, priv->props.vepa, NULL); + + g_object_set( + s_ipvlan, + NM_SETTING_IPVLAN_PARENT, + nm_device_parent_find_for_connection(device, nm_setting_ipvlan_get_parent(s_ipvlan)), + NULL); +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceIpvlanPrivate *priv = NM_DEVICE_IPVLAN_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_MODE: + g_value_set_string(value, platform_mode_to_string(priv->props.mode)); + break; + case PROP_PRIVATE: + g_value_set_boolean(value, priv->props.private_flag); + break; + case PROP_VEPA: + g_value_set_boolean(value, priv->props.vepa); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_device_ipvlan_init(NMDeviceIpvlan *self) +{} + +static const NMDBusInterfaceInfoExtended interface_info_device_ipvlan = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( + NM_DBUS_INTERFACE_DEVICE_IPVLAN, + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Mode", "s", NM_DEVICE_IPVLAN_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Private", + "b", + NM_DEVICE_IPVLAN_PRIVATE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Vepa", + "b", + NM_DEVICE_IPVLAN_VEPA), ), ), +}; + +static void +nm_device_ipvlan_class_init(NMDeviceIpvlanClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_ipvlan); + + device_class->connection_type_supported = NM_SETTING_IPVLAN_SETTING_NAME; + device_class->connection_type_check_compatible = NM_SETTING_IPVLAN_SETTING_NAME; + device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_IPVLAN); + + device_class->check_connection_compatible = check_connection_compatible; + device_class->create_and_realize = create_and_realize; + device_class->get_generic_capabilities = get_generic_capabilities; + device_class->is_available = is_available; + device_class->link_changed = link_changed; + device_class->update_connection = update_connection; + + obj_properties[PROP_MODE] = g_param_spec_string(NM_DEVICE_IPVLAN_MODE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_PRIVATE] = g_param_spec_boolean(NM_DEVICE_IPVLAN_PRIVATE, + "", + "", + TRUE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_VEPA] = g_param_spec_boolean(NM_DEVICE_IPVLAN_VEPA, + "", + "", + TRUE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); +} + +/*****************************************************************************/ + +#define NM_TYPE_IPVLAN_DEVICE_FACTORY (nm_ipvlan_device_factory_get_type()) +#define NM_IPVLAN_DEVICE_FACTORY(obj) \ + (_NM_G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_IPVLAN_DEVICE_FACTORY, NMIpvlanDeviceFactory)) + +static NMDevice * +create_device(NMDeviceFactory *factory, + const char *iface, + const NMPlatformLink *plink, + NMConnection *connection, + gboolean *out_ignore) +{ + NMSettingIpvlan *s_ipvlan; + + if (connection) { + s_ipvlan = _nm_connection_get_setting(connection, NM_TYPE_SETTING_IPVLAN); + nm_assert(s_ipvlan); + } + + return g_object_new(NM_TYPE_DEVICE_IPVLAN, + NM_DEVICE_IFACE, + iface, + NM_DEVICE_TYPE_DESC, + "Ipvlan", + NM_DEVICE_DEVICE_TYPE, + NM_DEVICE_TYPE_IPVLAN, + NM_DEVICE_LINK_TYPE, + NM_LINK_TYPE_IPVLAN, + NULL); +} + +static const char * +get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) +{ + NMSettingIpvlan *s_ipvlan; + NMSettingWired *s_wired; + const char *parent = NULL; + + g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_IPVLAN_SETTING_NAME), NULL); + + s_ipvlan = _nm_connection_get_setting(connection, NM_TYPE_SETTING_IPVLAN); + if (s_ipvlan) { + parent = nm_setting_ipvlan_get_parent(s_ipvlan); + if (parent) + return parent; + } + + /* Try the hardware address from the IPVLAN connection's hardware setting */ + s_wired = nm_connection_get_setting_wired(connection); + if (s_wired) + return nm_setting_wired_get_mac_address(s_wired); + else + return NULL; +} + +NM_DEVICE_FACTORY_DEFINE_INTERNAL( + IPVLAN, + Ipvlan, + ipvlan, + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_IPVLAN) + NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_IPVLAN_SETTING_NAME), + factory_class->create_device = create_device; + factory_class->get_connection_parent = get_connection_parent;); diff --git a/src/core/devices/nm-device-ipvlan.h b/src/core/devices/nm-device-ipvlan.h new file mode 100644 index 00000000..6a228abe --- /dev/null +++ b/src/core/devices/nm-device-ipvlan.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_DEVICE_IPVLAN_H__ +#define __NETWORKMANAGER_DEVICE_IPVLAN_H__ + +#include "nm-device.h" + +#define NM_TYPE_DEVICE_IPVLAN (nm_device_ipvlan_get_type()) +#define NM_DEVICE_IPVLAN(obj) \ + (_NM_G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_IPVLAN, NMDeviceIpvlan)) +#define NM_DEVICE_IPVLAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_IPVLAN, NMDeviceIpvlanClass)) +#define NM_IS_DEVICE_IPVLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_IPVLAN)) +#define NM_IS_DEVICE_IPVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_IPVLAN)) +#define NM_DEVICE_IPVLAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_IPVLAN, NMDeviceIpvlanClass)) + +#define NM_DEVICE_IPVLAN_PARENT "parent" +#define NM_DEVICE_IPVLAN_MODE "mode" +#define NM_DEVICE_IPVLAN_PRIVATE "private" +#define NM_DEVICE_IPVLAN_VEPA "vepa" + +typedef struct _NMDeviceIpvlan NMDeviceIpvlan; +typedef struct _NMDeviceIpvlanClass NMDeviceIpvlanClass; + +GType nm_device_ipvlan_get_type(void); + +#endif /* __NETWORKMANAGER_DEVICE_IPVLAN_H__ */ diff --git a/src/core/devices/nm-device-loopback.c b/src/core/devices/nm-device-loopback.c index ec72aa96..268e1fb1 100644 --- a/src/core/devices/nm-device-loopback.c +++ b/src/core/devices/nm-device-loopback.c @@ -59,14 +59,14 @@ complete_connection(NMDevice *device, NMConnection *const *existing_connections, GError **error) { - nm_utils_complete_generic_with_params(nm_device_get_platform(device), - connection, - NM_SETTING_LOOPBACK_SETTING_NAME, - existing_connections, - NULL, - _("Loopback connection"), - NULL, - nm_device_get_ip_iface(device)); + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_LOOPBACK_SETTING_NAME, + existing_connections, + NULL, + _("Loopback connection"), + NULL, + nm_device_get_ip_iface(device)); _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_LOOPBACK); diff --git a/src/core/devices/nm-device-macsec.c b/src/core/devices/nm-device-macsec.c index 32fab5be..89a06720 100644 --- a/src/core/devices/nm-device-macsec.c +++ b/src/core/devices/nm-device-macsec.c @@ -1022,36 +1022,18 @@ get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_MACSEC_SETTING_NAME), NULL); s_macsec = nm_connection_get_setting_macsec(connection); - g_assert(s_macsec); - - parent = nm_setting_macsec_get_parent(s_macsec); - if (parent) - return parent; + if (s_macsec) { + parent = nm_setting_macsec_get_parent(s_macsec); + if (parent) + return parent; + } /* Try the hardware address from the MACsec connection's hardware setting */ s_wired = nm_connection_get_setting_wired(connection); if (s_wired) return nm_setting_wired_get_mac_address(s_wired); - - return NULL; -} - -static char * -get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const char *parent_iface) -{ - NMSettingMacsec *s_macsec; - const char *ifname; - - g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_MACSEC_SETTING_NAME), NULL); - - s_macsec = nm_connection_get_setting_macsec(connection); - g_assert(s_macsec); - - if (!parent_iface) + else return NULL; - - ifname = nm_connection_get_interface_name(connection); - return g_strdup(ifname); } NM_DEVICE_FACTORY_DEFINE_INTERNAL( @@ -1061,5 +1043,4 @@ NM_DEVICE_FACTORY_DEFINE_INTERNAL( NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_MACSEC) NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_MACSEC_SETTING_NAME), factory_class->create_device = create_device; - factory_class->get_connection_parent = get_connection_parent; - factory_class->get_connection_iface = get_connection_iface;) + factory_class->get_connection_parent = get_connection_parent;); diff --git a/src/core/devices/nm-device-macvlan.c b/src/core/devices/nm-device-macvlan.c index 8cdef0cf..9501e8f1 100644 --- a/src/core/devices/nm-device-macvlan.c +++ b/src/core/devices/nm-device-macvlan.c @@ -232,9 +232,8 @@ create_and_realize(NMDevice *device, g_set_error(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, - "unsupported MACVLAN mode %u in connection %s", - nm_setting_macvlan_get_mode(s_macvlan), - nm_connection_get_uuid(connection)); + "unsupported MACVLAN mode %u", + nm_setting_macvlan_get_mode(s_macvlan)); return FALSE; } lnk.no_promisc = !nm_setting_macvlan_get_promiscuous(s_macvlan); @@ -365,8 +364,7 @@ complete_connection(NMDevice *device, NULL, _("MACVLAN connection"), NULL, - NULL, - TRUE); + NULL); s_macvlan = nm_connection_get_setting_macvlan(connection); if (!s_macvlan) { @@ -590,36 +588,18 @@ get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_MACVLAN_SETTING_NAME), NULL); s_macvlan = nm_connection_get_setting_macvlan(connection); - g_assert(s_macvlan); - - parent = nm_setting_macvlan_get_parent(s_macvlan); - if (parent) - return parent; + if (s_macvlan) { + parent = nm_setting_macvlan_get_parent(s_macvlan); + if (parent) + return parent; + } /* Try the hardware address from the MACVLAN connection's hardware setting */ s_wired = nm_connection_get_setting_wired(connection); if (s_wired) return nm_setting_wired_get_mac_address(s_wired); - - return NULL; -} - -static char * -get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const char *parent_iface) -{ - NMSettingMacvlan *s_macvlan; - const char *ifname; - - g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_MACVLAN_SETTING_NAME), NULL); - - s_macvlan = nm_connection_get_setting_macvlan(connection); - g_assert(s_macvlan); - - if (!parent_iface) + else return NULL; - - ifname = nm_connection_get_interface_name(connection); - return g_strdup(ifname); } NM_DEVICE_FACTORY_DEFINE_INTERNAL( @@ -629,5 +609,4 @@ NM_DEVICE_FACTORY_DEFINE_INTERNAL( NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVTAP) NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_MACVLAN_SETTING_NAME), factory_class->create_device = create_device; - factory_class->get_connection_parent = get_connection_parent; - factory_class->get_connection_iface = get_connection_iface;); + factory_class->get_connection_parent = get_connection_parent;); diff --git a/src/core/devices/nm-device-ppp.c b/src/core/devices/nm-device-ppp.c index 27566607..f44fe2f0 100644 --- a/src/core/devices/nm-device-ppp.c +++ b/src/core/devices/nm-device-ppp.c @@ -188,7 +188,7 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) s_pppoe = nm_device_get_applied_setting(device, NM_TYPE_SETTING_PPPOE); g_return_val_if_fail(s_pppoe, NM_ACT_STAGE_RETURN_FAILURE); - priv->ppp_mgr = nm_ppp_mgr_start(&((const NMPppMgrConfig){ + priv->ppp_mgr = nm_ppp_mgr_start(&((const NMPppMgrConfig) { .netns = nm_device_get_netns(device), .parent_iface = nm_setting_pppoe_get_parent(s_pppoe), .callback = _ppp_mgr_callback, @@ -380,20 +380,10 @@ get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) nm_assert(nm_connection_is_type(connection, NM_SETTING_PPPOE_SETTING_NAME)); s_pppoe = nm_connection_get_setting_pppoe(connection); - nm_assert(s_pppoe); - - return nm_setting_pppoe_get_parent(s_pppoe); -} - -static char * -get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const char *parent_iface) -{ - nm_assert(nm_connection_is_type(connection, NM_SETTING_PPPOE_SETTING_NAME)); - - if (!parent_iface) + if (s_pppoe) + return nm_setting_pppoe_get_parent(s_pppoe); + else return NULL; - - return g_strdup(nm_connection_get_interface_name(connection)); } NM_DEVICE_FACTORY_DEFINE_INTERNAL( @@ -403,6 +393,5 @@ NM_DEVICE_FACTORY_DEFINE_INTERNAL( NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_PPP) NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_PPPOE_SETTING_NAME), factory_class->get_connection_parent = get_connection_parent; - factory_class->get_connection_iface = get_connection_iface; factory_class->create_device = create_device; factory_class->match_connection = match_connection;); diff --git a/src/core/devices/nm-device-private.h b/src/core/devices/nm-device-private.h index 3bf5925c..2f73a01b 100644 --- a/src/core/devices/nm-device-private.h +++ b/src/core/devices/nm-device-private.h @@ -115,8 +115,8 @@ gboolean nm_device_sysctl_ip_conf_set(NMDevice *self, NML3ConfigData *nm_device_create_l3_config_data(NMDevice *self, NMIPConfigSource source); -const NML3ConfigData *nm_device_create_l3_config_data_from_connection(NMDevice *self, - NMConnection *connection); +NML3ConfigData *nm_device_create_l3_config_data_from_connection(NMDevice *self, + NMConnection *connection); void nm_device_ip_method_dhcp4_start(NMDevice *self); diff --git a/src/core/devices/nm-device-tun.c b/src/core/devices/nm-device-tun.c index 28b03cec..faab86d0 100644 --- a/src/core/devices/nm-device-tun.c +++ b/src/core/devices/nm-device-tun.c @@ -143,8 +143,7 @@ complete_connection(NMDevice *device, NULL, _("TUN connection"), NULL, - NULL, - TRUE); + NULL); s_tun = nm_connection_get_setting_tun(connection); if (!s_tun) { diff --git a/src/core/devices/nm-device-utils.c b/src/core/devices/nm-device-utils.c index ccb6292b..9fd7ac9d 100644 --- a/src/core/devices/nm-device-utils.c +++ b/src/core/devices/nm-device-utils.c @@ -355,7 +355,7 @@ nm_device_resolve_address(int addr_family, NMDnsSystemdResolved *resolved; info = g_new(ResolveAddrInfo, 1); - *info = (ResolveAddrInfo){ + *info = (ResolveAddrInfo) { .task = nm_g_task_new(NULL, cancellable, nm_device_resolve_address, callback, cb_data), .addr_family = addr_family, .address = nm_ip_addr_init(addr_family, address), diff --git a/src/core/devices/nm-device-vlan.c b/src/core/devices/nm-device-vlan.c index d4630999..59a429ca 100644 --- a/src/core/devices/nm-device-vlan.c +++ b/src/core/devices/nm-device-vlan.c @@ -241,7 +241,7 @@ create_and_realize(NMDevice *device, r = nm_platform_link_vlan_add(nm_device_get_platform(device), iface, parent_ifindex, - &((NMPlatformLnkVlan){ + &((NMPlatformLnkVlan) { .id = vlan_id, .flags = nm_setting_vlan_get_flags(s_vlan), .protocol = protocol, @@ -379,8 +379,7 @@ complete_connection(NMDevice *device, NULL, _("VLAN connection"), NULL, - NULL, - TRUE); + NULL); s_vlan = nm_connection_get_setting_vlan(connection); if (!s_vlan) { @@ -618,43 +617,35 @@ get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_VLAN_SETTING_NAME), NULL); s_vlan = nm_connection_get_setting_vlan(connection); - g_assert(s_vlan); - - parent = nm_setting_vlan_get_parent(s_vlan); - if (parent) - return parent; + if (s_vlan) { + parent = nm_setting_vlan_get_parent(s_vlan); + if (parent) + return parent; + } /* Try the hardware address from the VLAN connection's hardware setting */ s_wired = nm_connection_get_setting_wired(connection); if (s_wired) return nm_setting_wired_get_mac_address(s_wired); - - return NULL; + else + return NULL; } static char * get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const char *parent_iface) { - const char *ifname; NMSettingVlan *s_vlan; g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_VLAN_SETTING_NAME), NULL); - s_vlan = nm_connection_get_setting_vlan(connection); - g_assert(s_vlan); - if (!parent_iface) return NULL; - ifname = nm_connection_get_interface_name(connection); - if (ifname) - return g_strdup(ifname); - - /* If the connection doesn't specify the interface name for the VLAN - * device, we create one for it using the VLAN ID and the parent - * interface's name. - */ - return nmp_utils_new_vlan_name(parent_iface, nm_setting_vlan_get_id(s_vlan)); + s_vlan = nm_connection_get_setting_vlan(connection); + if (s_vlan) + return nmp_utils_new_vlan_name(parent_iface, nm_setting_vlan_get_id(s_vlan)); + else + return NULL; } NM_DEVICE_FACTORY_DEFINE_INTERNAL( diff --git a/src/core/devices/nm-device-vrf.c b/src/core/devices/nm-device-vrf.c index c3d31347..7dfd6504 100644 --- a/src/core/devices/nm-device-vrf.c +++ b/src/core/devices/nm-device-vrf.c @@ -48,7 +48,7 @@ do_update_properties(NMDeviceVrf *self, const NMPlatformLnkVrf *props) NMPlatformLnkVrf props_null; if (!props) { - props_null = (NMPlatformLnkVrf){}; + props_null = (NMPlatformLnkVrf) {}; props = &props_null; } @@ -184,8 +184,7 @@ complete_connection(NMDevice *device, NULL, _("VRF connection"), NULL, - NULL, - TRUE); + NULL); s_vrf = _nm_connection_get_setting(connection, NM_TYPE_SETTING_VRF); if (!s_vrf) { diff --git a/src/core/devices/nm-device-vxlan.c b/src/core/devices/nm-device-vxlan.c index 6a23d51e..4058287c 100644 --- a/src/core/devices/nm-device-vxlan.c +++ b/src/core/devices/nm-device-vxlan.c @@ -384,8 +384,7 @@ complete_connection(NMDevice *device, NULL, _("VXLAN connection"), NULL, - NULL, - TRUE); + NULL); s_vxlan = nm_connection_get_setting_vxlan(connection); if (!s_vxlan) { @@ -777,27 +776,10 @@ get_connection_parent(NMDeviceFactory *factory, NMConnection *connection) g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_VXLAN_SETTING_NAME), NULL); s_vxlan = nm_connection_get_setting_vxlan(connection); - g_assert(s_vxlan); - - return nm_setting_vxlan_get_parent(s_vxlan); -} - -static char * -get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const char *parent_iface) -{ - const char *ifname; - NMSettingVxlan *s_vxlan; - - g_return_val_if_fail(nm_connection_is_type(connection, NM_SETTING_VXLAN_SETTING_NAME), NULL); - - s_vxlan = nm_connection_get_setting_vxlan(connection); - g_assert(s_vxlan); - - if (nm_setting_vxlan_get_parent(s_vxlan) && !parent_iface) + if (s_vxlan) + return nm_setting_vxlan_get_parent(s_vxlan); + else return NULL; - - ifname = nm_connection_get_interface_name(connection); - return g_strdup(ifname); } NM_DEVICE_FACTORY_DEFINE_INTERNAL( @@ -807,5 +789,4 @@ NM_DEVICE_FACTORY_DEFINE_INTERNAL( NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_VXLAN) NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_VXLAN_SETTING_NAME), factory_class->create_device = create_device; - factory_class->get_connection_parent = get_connection_parent; - factory_class->get_connection_iface = get_connection_iface;); + factory_class->get_connection_parent = get_connection_parent;); diff --git a/src/core/devices/nm-device-wireguard.c b/src/core/devices/nm-device-wireguard.c index 00a8c718..4a08192e 100644 --- a/src/core/devices/nm-device-wireguard.c +++ b/src/core/devices/nm-device-wireguard.c @@ -430,7 +430,7 @@ get_extra_rules(NMDevice *device) g_ptr_array_add(extra_rules, nmp_object_new(NMP_OBJECT_TYPE_ROUTING_RULE, - &((const NMPlatformRoutingRule){ + &((const NMPlatformRoutingRule) { .priority = priority, .addr_family = addr_family, .action = FR_ACT_TO_TBL, @@ -440,7 +440,7 @@ get_extra_rules(NMDevice *device) g_ptr_array_add(extra_rules, nmp_object_new(NMP_OBJECT_TYPE_ROUTING_RULE, - &((const NMPlatformRoutingRule){ + &((const NMPlatformRoutingRule) { .priority = priority + 1u, .addr_family = addr_family, .action = FR_ACT_TO_TBL, @@ -588,7 +588,7 @@ _peers_add(NMDeviceWireGuard *self, NMWireGuardPeer *peer) nm_assert(!_peers_find(priv, peer)); peer_data = g_slice_new(PeerData); - *peer_data = (PeerData){ + *peer_data = (PeerData) { .self = self, .peer = nm_wireguard_peer_ref(peer), .ep_resolv = @@ -792,7 +792,7 @@ _peers_resolve_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) switch (g_inet_address_get_family(a)) { case G_SOCKET_FAMILY_IPV4: nm_assert(g_inet_address_get_native_size(a) == sizeof(struct in_addr)); - s->in = (struct sockaddr_in){ + s->in = (struct sockaddr_in) { .sin_family = AF_INET, .sin_port = htons(nm_sock_addr_endpoint_get_port( _nm_wireguard_peer_get_endpoint(peer_data->peer))), @@ -801,7 +801,7 @@ _peers_resolve_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) break; case G_SOCKET_FAMILY_IPV6: nm_assert(g_inet_address_get_native_size(a) == sizeof(struct in6_addr)); - s->in6 = (struct sockaddr_in6){ + s->in6 = (struct sockaddr_in6) { .sin6_family = AF_INET6, .sin6_port = htons(nm_sock_addr_endpoint_get_port( _nm_wireguard_peer_get_endpoint(peer_data->peer))), @@ -985,7 +985,7 @@ _peers_update(NMDeviceWireGuard *self, if (nm_clear_g_cancellable(&peer_data->ep_resolv.cancellable)) _peers_resolving_cnt_decrement(self); - peer_data->ep_resolv = (PeerEndpointResolveData){ + peer_data->ep_resolv = (PeerEndpointResolveData) { .sockaddr = sockaddr, .resolv_fail_count = 0, .cancellable = NULL, @@ -1166,7 +1166,7 @@ _peers_get_platform_list(NMDeviceWireGuardPrivate *priv, prefix = addr_family == AF_INET ? 32 : 128; g_array_append_val(allowed_ips, - ((NMPWireGuardAllowedIP){ + ((NMPWireGuardAllowedIP) { .family = addr_family, .mask = prefix, .addr = addrbin, @@ -1486,7 +1486,7 @@ link_config(NMDeviceWireGuard *self, _peers_update_all(self, s_wg, &peers_removed); - wg_lnk = (NMPlatformLnkWireGuard){}; + wg_lnk = (NMPlatformLnkWireGuard) {}; wg_change_flags = NM_PLATFORM_WIREGUARD_CHANGE_FLAG_NONE; @@ -1733,7 +1733,7 @@ _get_dev2_ip_config(NMDeviceWireGuard *self, int addr_family) } if (addr_family == AF_INET) { - rt.r4 = (NMPlatformIP4Route){ + rt.r4 = (NMPlatformIP4Route) { .network = addrbin.addr4, .plen = prefix, .ifindex = ip_ifindex, @@ -1742,7 +1742,7 @@ _get_dev2_ip_config(NMDeviceWireGuard *self, int addr_family) .metric = route_metric, }; } else { - rt.r6 = (NMPlatformIP6Route){ + rt.r6 = (NMPlatformIP6Route) { .network = addrbin.addr6, .plen = prefix, .ifindex = ip_ifindex, diff --git a/src/core/devices/nm-device-wpan.c b/src/core/devices/nm-device-wpan.c index 7885355d..67f845c8 100644 --- a/src/core/devices/nm-device-wpan.c +++ b/src/core/devices/nm-device-wpan.c @@ -53,8 +53,7 @@ complete_connection(NMDevice *device, NULL, _("WPAN connection"), NULL, - NULL, - TRUE); + NULL); s_wpan = NM_SETTING_WPAN(nm_connection_get_setting(connection, NM_TYPE_SETTING_WPAN)); if (!s_wpan) { diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 6c5a9b5a..e310a9c6 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -283,6 +283,7 @@ typedef struct { NML3IPv4LL *ipv4ll; NML3IPv4LLRegistration *ipv4ll_registation; GSource *timeout_source; + NMSettingIP4LinkLocal mode; } v4; struct { NML3IPv6LL *ipv6ll; @@ -315,6 +316,7 @@ typedef struct { NMEthtoolPauseState *pause; NMEthtoolChannelsState *channels; NMEthtoolEEEState *eee; + uint32_t fec_mode; } EthtoolState; typedef enum { @@ -615,6 +617,9 @@ typedef struct _NMDevicePrivate { NMPacrunnerConfId *pacrunner_conf_id; + const char *ipv4_method; + const char *ipv6_method; + struct { union { const NMDeviceIPState state; @@ -694,16 +699,6 @@ typedef struct _NMDevicePrivate { bool previous_mode_has : 1; } addrgenmode6_data; - struct { - NMLogDomain log_domain; - guint timeout; - guint watch; - GPid pid; - char *binary; - char *address; - guint deadline; - } gw_ping; - /* Firewall */ FirewallState fw_state : 4; NMFirewalldManager *fw_mgr; @@ -781,6 +776,8 @@ typedef struct _NMDevicePrivate { GVariant *ports_variant; /* Array of port devices D-Bus path */ char *prop_ip_iface; /* IP interface D-Bus property */ + GList *ping_operations; + GSource *ping_timeout; } NMDevicePrivate; G_DEFINE_ABSTRACT_TYPE(NMDevice, nm_device, NM_TYPE_DBUS_OBJECT) @@ -837,6 +834,7 @@ static void _set_mtu(NMDevice *self, guint32 mtu); static void _commit_mtu(NMDevice *self); static void _cancel_activation(NMDevice *self); +static void _dev_ipll4_check_fallback(NMDevice *self, const NML3ConfigData *l3cd_new); static void _dev_ipll4_notify_event(NMDevice *self); static void _dev_ip_state_check(NMDevice *self, int addr_family); @@ -1357,6 +1355,42 @@ _prop_get_ipv6_ra_timeout(NMDevice *self) 0); } +static NMSettingIPConfigRoutedDns +_prop_get_ipvx_routed_dns(NMDevice *self, int addr_family) +{ + NMSettingIPConfig *s_ip; + NMSettingIPConfigRoutedDns val; + int IS_IPv4; + const char *dns_mode; + NMSettingIPConfigRoutedDns fallback_value = NM_SETTING_IP_CONFIG_ROUTED_DNS_NO; + + g_return_val_if_fail(NM_IS_DEVICE(self), NM_SETTING_IP_CONFIG_ROUTED_DNS_NO); + IS_IPv4 = NM_IS_IPv4(addr_family); + + s_ip = nm_device_get_applied_setting(self, + IS_IPv4 ? NM_TYPE_SETTING_IP4_CONFIG + : NM_TYPE_SETTING_IP6_CONFIG); + if (!s_ip) + return NM_SETTING_IP_CONFIG_ROUTED_DNS_NO; + + val = nm_setting_ip_config_get_routed_dns(s_ip); + if (val != NM_SETTING_IP_CONFIG_ROUTED_DNS_DEFAULT) + return val; + + dns_mode = nm_config_data_get_dns_mode(nm_config_get_data(nm_config_get())); + if (nm_streq0(dns_mode, "dnsconfd")) { + fallback_value = NM_SETTING_IP_CONFIG_ROUTED_DNS_YES; + } + + return nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + IS_IPv4 ? NM_CON_DEFAULT("ipv4.routed-dns") + : NM_CON_DEFAULT("ipv6.routed-dns"), + self, + NM_SETTING_IP_CONFIG_ROUTED_DNS_NO, + NM_SETTING_IP_CONFIG_ROUTED_DNS_YES, + fallback_value); +} + static NMSettingConnectionMdns _prop_get_connection_mdns(NMDevice *self) { @@ -1603,6 +1637,7 @@ _prop_get_ipv4_link_local(NMDevice *self) { NMSettingIP4Config *s_ip4; NMSettingIP4LinkLocal link_local; + const char *method; s_ip4 = nm_device_get_applied_setting(self, NM_TYPE_SETTING_IP4_CONFIG); if (!s_ip4) @@ -1611,6 +1646,8 @@ _prop_get_ipv4_link_local(NMDevice *self) if (NM_IS_DEVICE_LOOPBACK(self)) return NM_SETTING_IP4_LL_DISABLED; + method = nm_setting_ip_config_get_method((NMSettingIPConfig *) s_ip4); + link_local = nm_setting_ip4_config_get_link_local(s_ip4); if (link_local == NM_SETTING_IP4_LL_DEFAULT) { @@ -1620,31 +1657,45 @@ _prop_get_ipv4_link_local(NMDevice *self) NM_CON_DEFAULT("ipv4.link-local"), self, NM_SETTING_IP4_LL_AUTO, - NM_SETTING_IP4_LL_ENABLED, + NM_SETTING_IP4_LL_FALLBACK, NM_SETTING_IP4_LL_DEFAULT); if (link_local == NM_SETTING_IP4_LL_DEFAULT) { /* If there is no global configuration for ipv4.link-local assume auto */ link_local = NM_SETTING_IP4_LL_AUTO; - } else if (link_local == NM_SETTING_IP4_LL_ENABLED - && nm_streq(nm_setting_ip_config_get_method((NMSettingIPConfig *) s_ip4), - NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) { - /* ipv4.method=disabled has higher priority than the global ipv4.link-local=enabled */ + } else if (NM_IN_SET(link_local, NM_SETTING_IP4_LL_ENABLED, NM_SETTING_IP4_LL_FALLBACK) + && nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) { + /* ipv4.method=disabled has higher priority than the global + * ipv4.link-local=enabled / ipv4.link-local=fallback */ link_local = NM_SETTING_IP4_LL_DISABLED; } else if (link_local == NM_SETTING_IP4_LL_DISABLED - && nm_streq(nm_setting_ip_config_get_method((NMSettingIPConfig *) s_ip4), - NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { + && nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { /* ipv4.method=link-local has higher priority than the global ipv4.link-local=disabled */ link_local = NM_SETTING_IP4_LL_ENABLED; } } if (link_local == NM_SETTING_IP4_LL_AUTO) { - link_local = nm_streq(nm_setting_ip_config_get_method((NMSettingIPConfig *) s_ip4), - NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) - ? NM_SETTING_IP4_LL_ENABLED - : NM_SETTING_IP4_LL_DISABLED; + /* ipv4.link-local=auto means enabled for ipv4.method=link-local, + * and disabled for anything else */ + if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { + link_local = NM_SETTING_IP4_LL_ENABLED; + } else { + link_local = NM_SETTING_IP4_LL_DISABLED; + } + } + + if (link_local == NM_SETTING_IP4_LL_FALLBACK + && nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { + /* ipv4.link-local=fallback with ipv4.method=link-local will + * always be on anyway, simplify logic */ + link_local = NM_SETTING_IP4_LL_ENABLED; } + nm_assert(NM_IN_SET(link_local, + NM_SETTING_IP4_LL_DISABLED, + NM_SETTING_IP4_LL_ENABLED, + NM_SETTING_IP4_LL_FALLBACK)); + return link_local; } @@ -1806,6 +1857,29 @@ _prop_get_ipvx_may_fail_cached(NMDevice *self, int addr_family, NMTernary *cache return _CACHED_BOOL(cache, _prop_get_ipvx_may_fail(self, addr_family)); } +static gboolean +_prop_get_ipv4_dhcp_ipv6_only_preferred(NMDevice *self) +{ + NMSettingIP4Config *s_ip4; + NMSettingIP4DhcpIpv6OnlyPreferred ipv6_only; + + s_ip4 = nm_device_get_applied_setting(self, NM_TYPE_SETTING_IP4_CONFIG); + if (!s_ip4) + return FALSE; + + ipv6_only = nm_setting_ip4_config_get_dhcp_ipv6_only_preferred(s_ip4); + if (ipv6_only != NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_DEFAULT) + return ipv6_only; + + return nm_config_data_get_connection_default_int64( + NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("ipv4.dhcp-ipv6-only-preferred"), + self, + NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_NO, + NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_YES, + NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_NO); +} + /** * _prop_get_ipvx_dhcp_iaid: * @self: the #NMDevice @@ -2005,6 +2079,59 @@ _prop_get_ipvx_dhcp_hostname_flags(NMDevice *self, int addr_family) return NM_DHCP_HOSTNAME_FLAGS_FQDN_DEFAULT_IP6; } +static gboolean +_prop_get_ipvx_dhcp_send_hostname(NMDevice *self, int addr_family) +{ + const int IS_IPv4 = NM_IS_IPv4(addr_family); + NMSettingIPConfig *s_ip = IS_IPv4 + ? nm_device_get_applied_setting(self, NM_TYPE_SETTING_IP4_CONFIG) + : nm_device_get_applied_setting(self, NM_TYPE_SETTING_IP6_CONFIG); + gboolean send_hostname; + gboolean send_hostname_v2; + + g_return_val_if_fail(s_ip, FALSE); + + send_hostname = nm_setting_ip_config_get_dhcp_send_hostname(s_ip); + send_hostname_v2 = nm_setting_ip_config_get_dhcp_send_hostname_v2(s_ip); + + if (send_hostname_v2 == NM_TERNARY_DEFAULT) { + send_hostname_v2 = nm_config_data_get_connection_default_int64( + NM_CONFIG_GET_DATA, + IS_IPv4 ? NM_CON_DEFAULT("ipv4.dhcp-send-hostname") + : NM_CON_DEFAULT("ipv6.dhcp-send-hostname"), + self, + NM_TERNARY_FALSE, + NM_TERNARY_TRUE, + send_hostname ? NM_TERNARY_TRUE : NM_TERNARY_FALSE); + } + + return send_hostname_v2; +} + +static gboolean +_prop_get_connection_ip_ping_addresses_require_all(NMDevice *self, NMSettingConnection *s_con) +{ + NMTernary ip_ping_addresses_require_all; + const char *s; + + ip_ping_addresses_require_all = nm_setting_connection_get_ip_ping_addresses_require_all(s_con); + + if (ip_ping_addresses_require_all != NM_TERNARY_DEFAULT) { + return ip_ping_addresses_require_all; + } else { + s = nm_config_data_get_connection_default( + NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("connection.ip-ping-addresses-require-all"), + self); + + if (s) { + return _nm_utils_ascii_str_to_bool(s, FALSE); + } + } + + return FALSE; +} + static const char * _prop_get_connection_mud_url(NMDevice *self, NMSettingConnection *s_con) { @@ -2564,6 +2691,19 @@ _ethtool_features_reset(NMDevice *self, NMPlatform *platform, EthtoolState *etht } static void +_ethtool_fec_reset(NMDevice *self, NMPlatform *platform, EthtoolState *ethtool_state) +{ + if (ethtool_state->fec_mode) { + if (!nm_platform_ethtool_set_fec_mode(platform, + ethtool_state->ifindex, + ethtool_state->fec_mode)) + _LOGW(LOGD_DEVICE, "ethtool: failure resetting FEC"); + else + _LOGD(LOGD_DEVICE, "ethtool: FEC successfully reset"); + } +} + +static void _ethtool_features_set(NMDevice *self, NMPlatform *platform, EthtoolState *ethtool_state, @@ -2595,6 +2735,55 @@ _ethtool_features_set(NMDevice *self, } static void +_ethtool_fec_set(NMDevice *self, + NMPlatform *platform, + EthtoolState *ethtool_state, + NMSettingEthtool *s_ethtool) +{ + uint32_t old_fec_mode; + uint32_t fec_mode = NM_SETTING_ETHTOOL_FEC_MODE_NONE; + GHashTable *hash; + GHashTableIter iter; + const char *name; + GVariant *variant; + + nm_assert(NM_IS_DEVICE(self)); + nm_assert(NM_IS_PLATFORM(platform)); + nm_assert(NM_IS_SETTING_ETHTOOL(s_ethtool)); + nm_assert(ethtool_state); + nm_assert(!ethtool_state->fec_mode); + + hash = _nm_setting_option_hash(NM_SETTING(s_ethtool), FALSE); + if (!hash) + return; + + g_hash_table_iter_init(&iter, hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &variant)) { + NMEthtoolID ethtool_id = nm_ethtool_id_get_by_name(name); + + if (!nm_ethtool_id_is_fec(ethtool_id)) + continue; + + nm_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_UINT32)); + fec_mode = g_variant_get_uint32(variant); + } + + nm_platform_ethtool_get_fec_mode(platform, ethtool_state->ifindex, &old_fec_mode); + + /* The NM_SETTING_ETHTOOL_FEC_MODE_NONE is query only value, hence do nothing. */ + if (!fec_mode || fec_mode == NM_SETTING_ETHTOOL_FEC_MODE_NONE) { + return; + } + + if (!nm_platform_ethtool_set_fec_mode(platform, ethtool_state->ifindex, fec_mode)) + _LOGW(LOGD_DEVICE, "ethtool: failure setting FEC %d", fec_mode); + else { + _LOGD(LOGD_DEVICE, "ethtool: FEC %d successfully set", fec_mode); + ethtool_state->fec_mode = old_fec_mode; + } +} + +static void _ethtool_coalesce_reset(NMDevice *self, NMPlatform *platform, EthtoolState *ethtool_state) { gs_free NMEthtoolCoalesceState *coalesce = NULL; @@ -3075,6 +3264,7 @@ _ethtool_state_reset(NMDevice *self) _ethtool_pause_reset(self, platform, ethtool_state); _ethtool_channels_reset(self, platform, ethtool_state); _ethtool_eee_reset(self, platform, ethtool_state); + _ethtool_fec_reset(self, platform, ethtool_state); } static void @@ -3111,9 +3301,11 @@ _ethtool_state_set(NMDevice *self) _ethtool_pause_set(self, platform, ethtool_state, s_ethtool); _ethtool_channels_set(self, platform, ethtool_state, s_ethtool); _ethtool_eee_set(self, platform, ethtool_state, s_ethtool); + _ethtool_fec_set(self, platform, ethtool_state, s_ethtool); if (ethtool_state->features || ethtool_state->coalesce || ethtool_state->ring - || ethtool_state->pause || ethtool_state->channels || ethtool_state->eee) + || ethtool_state->pause || ethtool_state->channels || ethtool_state->eee + || ethtool_state->fec_mode != 0) priv->ethtool_state = g_steal_pointer(ðtool_state); } @@ -3124,7 +3316,7 @@ link_properties_fill_from_setting(NMDevice *self, NMPlatformLinkProps *props) NMSettingLink *s_link; gint64 v; - *props = (NMPlatformLinkProps){}; + *props = (NMPlatformLinkProps) {}; s_link = nm_device_get_applied_setting(self, NM_TYPE_SETTING_LINK); if (!s_link) @@ -3336,7 +3528,7 @@ nm_device_create_l3_config_data(NMDevice *self, NMIPConfigSource source) return nm_l3_config_data_new(nm_device_get_multi_index(self), ifindex, source); } -const NML3ConfigData * +NML3ConfigData * nm_device_create_l3_config_data_from_connection(NMDevice *self, NMConnection *connection) { NML3ConfigData *l3cd; @@ -4610,15 +4802,6 @@ _dev_l3_cfg_notify_cb(NML3Cfg *l3cfg, const NML3ConfigNotifyData *notify_data, N nm_assert(l3cfg == priv->l3cfg); switch (notify_data->notify_type) { - case NM_L3_CONFIG_NOTIFY_TYPE_L3CD_CHANGED: - if (notify_data->l3cd_changed.commited) { - g_signal_emit(self, - signals[L3CD_CHANGED], - 0, - notify_data->l3cd_changed.l3cd_old, - notify_data->l3cd_changed.l3cd_new); - } - return; case NM_L3_CONFIG_NOTIFY_TYPE_ACD_EVENT: { const NML3AcdAddrInfo *addr_info = ¬ify_data->acd_event.info; @@ -4646,16 +4829,25 @@ _dev_l3_cfg_notify_cb(NML3Cfg *l3cfg, const NML3ConfigNotifyData *notify_data, N const NML3ConfigData *l3cd; NMDeviceState state = nm_device_get_state(self); + l3cd = nm_l3cfg_get_combined_l3cd(l3cfg, TRUE); if (state >= NM_DEVICE_STATE_IP_CONFIG && state < NM_DEVICE_STATE_DEACTIVATING) { /* FIXME(l3cfg): MTU handling should be moved to l3cfg. */ - l3cd = nm_l3cfg_get_combined_l3cd(l3cfg, TRUE); if (l3cd) priv->ip6_mtu = nm_l3_config_data_get_ip6_mtu(l3cd); _commit_mtu(self); } + _dev_ipll4_check_fallback(self, l3cd); return; } case NM_L3_CONFIG_NOTIFY_TYPE_POST_COMMIT: + if (notify_data->commit.l3cd_changed) { + g_signal_emit(self, + signals[L3CD_CHANGED], + 0, + notify_data->commit.l3cd_old, + notify_data->commit.l3cd_new); + } + if (priv->ipshared_data_4.state == NM_DEVICE_IP_STATE_PENDING && !priv->ipshared_data_4.v4.dnsmasq_manager && priv->ipshared_data_4.v4.l3cd) { _dev_ipshared4_spawn_dnsmasq(self); @@ -5635,6 +5827,8 @@ nm_device_get_route_metric_default(NMDeviceType device_type) return 400; case NM_DEVICE_TYPE_MACVLAN: return 410; + case NM_DEVICE_TYPE_IPVLAN: + return 420; case NM_DEVICE_TYPE_BRIDGE: return 425; case NM_DEVICE_TYPE_TUN: @@ -7971,9 +8165,9 @@ sriov_op_queue(NMDevice *self, * grace period we pull the plug and cancel it. */ op = g_slice_new(SriovOp); - *op = (SriovOp){ + *op = (SriovOp) { .sriov_params = - (NMPlatformSriovParams){ + (NMPlatformSriovParams) { .num_vfs = num_vfs, .autoprobe = autoprobe, .eswitch_mode = (_NMSriovEswitchMode) eswitch_mode, @@ -8554,7 +8748,7 @@ port_state_changed(NMDevice *port, /** * nm_device_controller_add_port: * @self: the controller device - * @port: the port device to attach as port + * @port: the port device to attach as port * @configure: pass %TRUE if the port should be configured by the controller, or * %FALSE if it is already configured outside NetworkManager * @@ -10722,6 +10916,25 @@ _dev_ipll4_start(NMDevice *self) nm_l3_ipv4ll_register_new(priv->ipll_data_4.v4.ipv4ll, timeout_msec); } +static void +_dev_ipll4_check_fallback(NMDevice *self, const NML3ConfigData *l3cd_new) +{ + gboolean has_non_ll; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + + if (!l3cd_new || priv->ipll_data_4.v4.mode != NM_SETTING_IP4_LL_FALLBACK) { + return; + } + + has_non_ll = nm_l3_config_data_get_flags(l3cd_new) & NM_L3_CONFIG_DAT_FLAGS_HAS_IPV4_NON_LL; + _LOGT_ipll(AF_INET, "%s fallback", has_non_ll ? "cleanup" : "start"); + if (has_non_ll) { + _dev_ipllx_cleanup(self, AF_INET); + } else { + _dev_ipll4_start(self); + } +} + /*****************************************************************************/ static const char * @@ -10963,8 +11176,8 @@ _dev_ipmanual_check_ready(NMDevice *self) static void _dev_ipmanual_start(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - nm_auto_unref_l3cd const NML3ConfigData *l3cd = NULL; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL; if (priv->ipmanual_data.state_4 != NM_DEVICE_IP_STATE_NONE || priv->ipmanual_data.state_6 != NM_DEVICE_IP_STATE_NONE) @@ -10974,6 +11187,13 @@ _dev_ipmanual_start(NMDevice *self) l3cd = nm_device_create_l3_config_data_from_connection(self, nm_device_get_applied_connection(self)); + + if (_prop_get_ipvx_routed_dns(self, AF_INET) == NM_SETTING_IP_CONFIG_ROUTED_DNS_YES) { + nm_l3_config_data_set_routed_dns(l3cd, AF_INET, TRUE); + } + if (_prop_get_ipvx_routed_dns(self, AF_INET6) == NM_SETTING_IP_CONFIG_ROUTED_DNS_YES) { + nm_l3_config_data_set_routed_dns(l3cd, AF_INET6, TRUE); + } } if (!l3cd) { @@ -11130,6 +11350,8 @@ _dev_ipdhcpx_notify(NMDhcpClient *client, const NMDhcpClientNotifyData *notify_d const NML3ConfigData *dhcp_l3cd = priv->l3cds[L3_CONFIG_DATA_TYPE_DHCP_X(IS_IPv4)].d; _LOGT_ipdhcp(addr_family, "lease lost"); + _dev_ipdhcpx_set_state(self, addr_family, NM_DEVICE_IP_STATE_PENDING); + _dev_ip_state_check_async(self, addr_family); if (dhcp_l3cd && nm_l3cfg_remove_config( priv->l3cfg, @@ -11273,7 +11495,8 @@ _dev_ipdhcpx_start(NMDevice *self, int addr_family) gboolean hostname_is_fqdn; gboolean send_client_id; guint8 dscp; - gboolean dscp_explicit = FALSE; + gboolean dscp_explicit = FALSE; + gboolean ipv6_only_pref = FALSE; client_id = _prop_get_ipv4_dhcp_client_id(self, connection, hwaddr, &send_client_id); dscp = _prop_get_ipv4_dhcp_dscp(self, &dscp_explicit); @@ -11292,7 +11515,18 @@ _dev_ipdhcpx_start(NMDevice *self, int addr_family) hostname = nm_setting_ip_config_get_dhcp_hostname(s_ip); } - config = (NMDhcpClientConfig){ + if (_prop_get_ipv4_dhcp_ipv6_only_preferred(self)) { + if (nm_streq0(priv->ipv6_method, NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) { + _LOGI_ipdhcp( + addr_family, + "not requesting the \"IPv6-only preferred\" option because IPv6 is disabled"); + } else { + _LOGD_ipdhcp(addr_family, "requesting the \"IPv6-only preferred\" option"); + ipv6_only_pref = TRUE; + } + } + + config = (NMDhcpClientConfig) { .addr_family = AF_INET, .l3cfg = nm_device_get_l3cfg(self), .iface = nm_device_get_ip_iface(self), @@ -11300,7 +11534,7 @@ _dev_ipdhcpx_start(NMDevice *self, int addr_family) .uuid = nm_connection_get_uuid(connection), .hwaddr = hwaddr, .bcast_hwaddr = bcast_hwaddr, - .send_hostname = nm_setting_ip_config_get_dhcp_send_hostname(s_ip), + .send_hostname = _prop_get_ipvx_dhcp_send_hostname(self, AF_INET), .hostname = hostname, .hostname_flags = _prop_get_ipvx_dhcp_hostname_flags(self, AF_INET), .client_id = client_id, @@ -11312,11 +11546,12 @@ _dev_ipdhcpx_start(NMDevice *self, int addr_family) .reject_servers = reject_servers, .v4 = { - .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, + .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, + .ipv6_only_preferred = ipv6_only_pref, }, .previous_lease = priv->l3cds[L3_CONFIG_DATA_TYPE_DHCP_X(IS_IPv4)].d, }; @@ -11333,13 +11568,13 @@ _dev_ipdhcpx_start(NMDevice *self, int addr_family) iaid = _prop_get_ipvx_dhcp_iaid(self, AF_INET6, connection, FALSE, &iaid_explicit); duid = _prop_get_ipv6_dhcp_duid(self, connection, hwaddr, &enforce_duid); - config = (NMDhcpClientConfig){ + config = (NMDhcpClientConfig) { .addr_family = AF_INET6, .l3cfg = nm_device_get_l3cfg(self), .iface = nm_device_get_ip_iface(self), .iface_type_log = nm_device_get_type_desc_for_log(self), .uuid = nm_connection_get_uuid(connection), - .send_hostname = nm_setting_ip_config_get_dhcp_send_hostname(s_ip), + .send_hostname = _prop_get_ipvx_dhcp_send_hostname(self, AF_INET6), .hostname = nm_setting_ip_config_get_dhcp_hostname(s_ip), .hostname_flags = _prop_get_ipvx_dhcp_hostname_flags(self, AF_INET6), .client_id = duid, @@ -12629,6 +12864,9 @@ _dev_sysctl_save_ip6_properties(NMDevice *self) if (!ifname) return; + if (!g_file_test("/proc/sys/net/ipv6", G_FILE_TEST_IS_DIR)) + return; + for (i = 0; i < G_N_ELEMENTS(ip6_properties_to_save); i++) { value = nm_platform_sysctl_ip_conf_get(platform, AF_INET6, ifname, ip6_properties_to_save[i]); @@ -12648,6 +12886,9 @@ _dev_sysctl_restore_ip6_properties(NMDevice *self) gpointer key; gpointer value; + if (!g_file_test("/proc/sys/net/ipv6", G_FILE_TEST_IS_DIR)) + return; + g_hash_table_iter_init(&iter, priv->ip6_saved_properties); while (g_hash_table_iter_next(&iter, &key, &value)) nm_device_sysctl_ip_conf_set(self, AF_INET6, key, value); @@ -12769,7 +13010,7 @@ get_ip_method_auto(NMDevice *self, int addr_family) } static void -activate_stage3_ip_config_for_addr_family(NMDevice *self, int addr_family, const char *method) +activate_stage3_ip_config_for_addr_family(NMDevice *self, int addr_family) { const int IS_IPv4 = NM_IS_IPv4(addr_family); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); @@ -12819,30 +13060,31 @@ activate_stage3_ip_config_for_addr_family(NMDevice *self, int addr_family, const goto out_devip; if (IS_IPv4) { - if (_prop_get_ipv4_link_local(self) == NM_SETTING_IP4_LL_ENABLED) + 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); - if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) + if (nm_streq(priv->ipv4_method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) _dev_ipdhcpx_start(self, AF_INET); - else if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { + else if (nm_streq(priv->ipv4_method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { /* pass */ - } else if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) + } else if (nm_streq(priv->ipv4_method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) _dev_ipshared4_start(self); - else if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) + else if (nm_streq(priv->ipv4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) priv->ip_data_x[IS_IPv4].is_disabled = TRUE; - else if (nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { + else if (nm_streq(priv->ipv4_method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { /* pass */ } else nm_assert_not_reached(); } if (!IS_IPv4) { - if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) { + if (nm_streq(priv->ipv6_method, NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) { if (!priv->ip_data_x[IS_IPv4].is_disabled) { priv->ip_data_x[IS_IPv4].is_disabled = TRUE; nm_device_sysctl_ip_conf_set(self, AF_INET6, "disable_ipv6", "1"); } - } else if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { + } else if (nm_streq(priv->ipv6_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { if (!priv->ip_data_x[IS_IPv4].is_ignore) { priv->ip_data_x[IS_IPv4].is_ignore = TRUE; if (priv->controller) { @@ -12875,15 +13117,15 @@ activate_stage3_ip_config_for_addr_family(NMDevice *self, int addr_family, const } else { _dev_ipll6_start(self); - if (NM_IN_STRSET(method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) + if (NM_IN_STRSET(priv->ipv6_method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) _dev_ipac6_start(self); - else if (NM_IN_STRSET(method, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) + else if (NM_IN_STRSET(priv->ipv6_method, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) _dev_ipshared6_start(self); - else if (nm_streq(method, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) { + else if (nm_streq(priv->ipv6_method, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) { priv->ipdhcp_data_6.v6.mode = NM_NDISC_DHCP_LEVEL_MANAGED; _dev_ipdhcpx_start(self, AF_INET6); } else - nm_assert(NM_IN_STRSET(method, + nm_assert(NM_IN_STRSET(priv->ipv6_method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)); } @@ -12984,8 +13226,6 @@ activate_stage3_ip_config(NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); NMDeviceClass *klass = NM_DEVICE_GET_CLASS(self); int ifindex; - const char *ipv4_method; - const char *ipv6_method; /* stage3 is different from stage1+2. * @@ -13035,17 +13275,17 @@ activate_stage3_ip_config(NMDevice *self) } nm_assert(ifindex <= 0 || priv->fw_state == FIREWALL_STATE_INITIALIZED); - ipv4_method = nm_device_get_effective_ip_config_method(self, AF_INET); - if (nm_streq(ipv4_method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { + priv->ipv4_method = nm_device_get_effective_ip_config_method(self, AF_INET); + if (nm_streq(priv->ipv4_method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { /* "auto" usually means DHCPv4 or autoconf6, but it doesn't have to be. Subclasses * can overwrite it. For example, you cannot run DHCPv4 on PPP/WireGuard links. */ - ipv4_method = klass->get_ip_method_auto(self, AF_INET); + priv->ipv4_method = klass->get_ip_method_auto(self, AF_INET); } - ipv6_method = nm_device_get_effective_ip_config_method(self, AF_INET6); + priv->ipv6_method = nm_device_get_effective_ip_config_method(self, AF_INET6); if (!g_file_test("/proc/sys/net/ipv6", G_FILE_TEST_IS_DIR)) { _NMLOG_ip((nm_device_managed_type_is_external(self) - || NM_IN_STRSET(ipv6_method, + || NM_IN_STRSET(priv->ipv6_method, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NM_SETTING_IP6_CONFIG_METHOD_DISABLED, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) @@ -13053,9 +13293,9 @@ activate_stage3_ip_config(NMDevice *self) : LOGL_WARN, AF_INET6, "IPv6 not supported by kernel resulting in \"ipv6.method=disabled\""); - ipv6_method = NM_SETTING_IP6_CONFIG_METHOD_DISABLED; - } else if (nm_streq(ipv6_method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { - ipv6_method = klass->get_ip_method_auto(self, AF_INET6); + priv->ipv6_method = NM_SETTING_IP6_CONFIG_METHOD_DISABLED; + } else if (nm_streq(priv->ipv6_method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { + priv->ipv6_method = klass->get_ip_method_auto(self, AF_INET6); } if (priv->ip_data_4.do_reapply) { @@ -13064,7 +13304,7 @@ activate_stage3_ip_config(NMDevice *self) _cleanup_ip_pre(self, AF_INET, CLEANUP_TYPE_KEEP_REAPPLY, - nm_streq(ipv4_method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)); + nm_streq(priv->ipv4_method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)); } if (priv->ip_data_6.do_reapply) { _LOGD_ip(AF_INET6, "reapply..."); @@ -13072,7 +13312,7 @@ activate_stage3_ip_config(NMDevice *self) _cleanup_ip_pre(self, AF_INET6, CLEANUP_TYPE_KEEP_REAPPLY, - nm_streq(ipv6_method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)); + nm_streq(priv->ipv6_method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)); } if (priv->state < NM_DEVICE_STATE_IP_CONFIG) { @@ -13103,7 +13343,7 @@ activate_stage3_ip_config(NMDevice *self) if (!nm_device_managed_type_is_external(self) && (!klass->ready_for_ip_config || klass->ready_for_ip_config(self, TRUE))) { if (priv->ipmanual_data.state_6 == NM_DEVICE_IP_STATE_NONE - && !NM_IN_STRSET(ipv6_method, + && !NM_IN_STRSET(priv->ipv6_method, NM_SETTING_IP6_CONFIG_METHOD_DISABLED, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { /* Ensure the MTU makes sense. If it was below 1280 the kernel would not @@ -13127,8 +13367,8 @@ activate_stage3_ip_config(NMDevice *self) _dev_ipmanual_start(self); } - activate_stage3_ip_config_for_addr_family(self, AF_INET, ipv4_method); - activate_stage3_ip_config_for_addr_family(self, AF_INET6, ipv6_method); + activate_stage3_ip_config_for_addr_family(self, AF_INET); + activate_stage3_ip_config_for_addr_family(self, AF_INET6); } void @@ -13349,6 +13589,9 @@ _dev_ipshared4_spawn_dnsmasq(NMDevice *self) NMConnection *applied; gs_unref_array GArray *conflicts = NULL; gboolean ready; + NMSettingIPConfig *s_ip4 = NULL; + const char *shared_dhcp_range; + int shared_dhcp_lease_time; nm_assert(priv->ipshared_data_4.v4.firewall_config); nm_assert(priv->ipshared_data_4.v4.dnsmasq_state_id == 0); @@ -13394,9 +13637,14 @@ _dev_ipshared4_spawn_dnsmasq(NMDevice *self) break; } + s_ip4 = nm_device_get_applied_setting(self, NM_TYPE_SETTING_IP4_CONFIG); + shared_dhcp_range = nm_setting_ip_config_get_shared_dhcp_range(s_ip4); + shared_dhcp_lease_time = nm_setting_ip_config_get_shared_dhcp_lease_time(s_ip4); priv->ipshared_data_4.v4.dnsmasq_manager = nm_dnsmasq_manager_new(ip_iface); if (!nm_dnsmasq_manager_start(priv->ipshared_data_4.v4.dnsmasq_manager, priv->ipshared_data_4.v4.l3cd, + shared_dhcp_range, + shared_dhcp_lease_time, announce_android_metered, &error)) { _LOGW_ipshared(AF_INET, "could not start dnsmasq: %s", error->message); @@ -13567,8 +13815,11 @@ _cleanup_ip_pre(NMDevice *self, int addr_family, CleanupType cleanup_type, gbool _dev_ipdhcpx_cleanup(self, addr_family, !preserve_dhcp || !keep_reapply, FALSE); - if (!IS_IPv4) + if (IS_IPv4) { + priv->ipll_data_4.v4.mode = NM_SETTING_IP4_LL_DISABLED; + } else { _dev_ipac6_cleanup(self); + } _dev_ipllx_cleanup(self, addr_family); @@ -14125,7 +14376,7 @@ impl_device_reapply(NMDBusObject *obj, } reapply_data = g_slice_new(ReapplyData); - *reapply_data = (ReapplyData){ + *reapply_data = (ReapplyData) { .connection = connection, .version_id = version_id, .reapply_flags = reapply_flags, @@ -14708,6 +14959,37 @@ _dispatcher_complete_proceed_state(NMDispatcherCallId *call_id, gpointer user_da /*****************************************************************************/ +typedef struct { + NMLogDomain log_domain; + NMDevice *device; + gboolean ping_addresses_require_all; + GSource *watch; + GPid pid; + char *binary; + char *address; + guint deadline; +} PingOperation; + +static PingOperation * +ping_operation_new(NMDevice *self, + NMLogDomain log_domain, + const char *address, + const char *ping_binary, + guint ping_timeout, + gboolean ip_ping_addresses_require_all) +{ + PingOperation *ping_op = g_new0(PingOperation, 1); + + ping_op->device = self; + ping_op->log_domain = log_domain; + ping_op->address = g_strdup(address); + ping_op->binary = g_strdup(ping_binary); + ping_op->deadline = ping_timeout + 10; + ping_op->ping_addresses_require_all = ip_ping_addresses_require_all; + + return ping_op; +} + static void ip_check_pre_up(NMDevice *self) { @@ -14730,49 +15012,50 @@ ip_check_pre_up(NMDevice *self) } static void -ip_check_gw_ping_cleanup(NMDevice *self) +cleanup_ping_operation(PingOperation *ping_op) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - - nm_clear_g_source(&priv->gw_ping.watch); - nm_clear_g_source(&priv->gw_ping.timeout); + if (ping_op->watch) { + nm_clear_g_source_inst(&ping_op->watch); + } - if (priv->gw_ping.pid) { - nm_utils_kill_child_async(priv->gw_ping.pid, + if (ping_op->pid) { + nm_utils_kill_child_async(ping_op->pid, SIGTERM, - priv->gw_ping.log_domain, + ping_op->log_domain, "ping", 1000, NULL, NULL); - priv->gw_ping.pid = 0; + ping_op->pid = 0; } - nm_clear_g_free(&priv->gw_ping.binary); - nm_clear_g_free(&priv->gw_ping.address); + nm_clear_g_free(&ping_op->binary); + nm_clear_g_free(&ping_op->address); + + g_free(ping_op); } static gboolean -spawn_ping(NMDevice *self) +spawn_ping_for_operation(NMDevice *self, PingOperation *ping_op) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); gs_free char *str_timeout = NULL; gs_free char *tmp_str = NULL; - const char *args[] = {priv->gw_ping.binary, + const char *args[] = {ping_op->binary, "-I", nm_device_get_ip_iface(self), "-c", "1", "-w", NULL, - priv->gw_ping.address, + ping_op->address, NULL}; gs_free_error GError *error = NULL; gboolean ret; - args[6] = str_timeout = g_strdup_printf("%u", priv->gw_ping.deadline); - tmp_str = g_strjoinv(" ", (char **) args); - _LOGD(priv->gw_ping.log_domain, "ping: running '%s'", tmp_str); + args[6] = str_timeout = g_strdup_printf("%u", ping_op->deadline); + + tmp_str = g_strjoinv(" ", (char **) args); + _LOGD(ping_op->log_domain, "ping: running '%s'", tmp_str); ret = g_spawn_async("/", (char **) args, @@ -14780,14 +15063,13 @@ spawn_ping(NMDevice *self) G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, - &priv->gw_ping.pid, + &ping_op->pid, &error); - if (!ret) { - _LOGW(priv->gw_ping.log_domain, - "ping: could not spawn %s: %s", - priv->gw_ping.binary, - error->message); + if (ret) { + ping_op->watch = nm_g_child_watch_add_source(ping_op->pid, ip_check_ping_watch_cb, ping_op); + } else { + _LOGD(ping_op->log_domain, "ping: could not spawn %s: %s", ping_op->binary, error->message); } return ret; @@ -14796,16 +15078,19 @@ spawn_ping(NMDevice *self) static gboolean respawn_ping_cb(gpointer user_data) { - NMDevice *self = NM_DEVICE(user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + PingOperation *ping_op = (PingOperation *) user_data; + NMDevice *self = ping_op->device; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - priv->gw_ping.watch = 0; + nm_clear_g_source_inst(&ping_op->watch); - if (spawn_ping(self)) { - priv->gw_ping.watch = g_child_watch_add(priv->gw_ping.pid, ip_check_ping_watch_cb, self); - } else { - ip_check_gw_ping_cleanup(self); - ip_check_pre_up(self); + if (!spawn_ping_for_operation(self, ping_op)) { + cleanup_ping_operation(ping_op); + priv->ping_operations = g_list_remove(priv->ping_operations, ping_op); + + if (g_list_length(priv->ping_operations) == 0) { + ip_check_pre_up(self); + } } return FALSE; @@ -14814,34 +15099,64 @@ respawn_ping_cb(gpointer user_data) static void ip_check_ping_watch_cb(GPid pid, int status, gpointer user_data) { - NMDevice *self = NM_DEVICE(user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - NMLogDomain log_domain = priv->gw_ping.log_domain; - gboolean success = FALSE; + PingOperation *ping_op = (PingOperation *) user_data; + NMDevice *self = ping_op->device; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + gboolean success = FALSE; - if (!priv->gw_ping.watch) + if (!ping_op->watch) return; - priv->gw_ping.watch = 0; - priv->gw_ping.pid = 0; + + nm_clear_g_source_inst(&ping_op->watch); + ping_op->pid = 0; if (WIFEXITED(status)) { if (WEXITSTATUS(status) == 0) { - _LOGD(log_domain, "ping: gateway ping succeeded"); + _LOGD(ping_op->log_domain, "ping: ping succeeded on %s", ping_op->address); success = TRUE; } else { - _LOGW(log_domain, "ping: gateway ping failed with error code %d", WEXITSTATUS(status)); + _LOGD(ping_op->log_domain, + "ping: ping failed with error code %d on %s", + WEXITSTATUS(status), + ping_op->address); } - } else - _LOGW(log_domain, "ping: stopped unexpectedly with status %d", status); + } else { + _LOGD(ping_op->log_domain, + "ping: stopped unexpectedly with status %d on %s", + status, + ping_op->address); + } if (success) { - /* We've got connectivity, proceed to pre_up */ - ip_check_gw_ping_cleanup(self); - ip_check_pre_up(self); + if (ping_op->ping_addresses_require_all) { + cleanup_ping_operation(ping_op); + priv->ping_operations = g_list_remove(priv->ping_operations, ping_op); + if (g_list_length(priv->ping_operations) == 0) { + _LOGD(ping_op->log_domain, + "ping: ip-ping-addresses requires all, all ping checks on ip-ping-addresses " + "succeeded"); + if (priv->ping_timeout) + nm_clear_g_source_inst(&priv->ping_timeout); + ip_check_pre_up(self); + } + } else { + nm_assert(priv->ping_operations); + + g_list_free_full(priv->ping_operations, (GDestroyNotify) cleanup_ping_operation); + priv->ping_operations = NULL; + + if (priv->ping_timeout) + nm_clear_g_source_inst(&priv->ping_timeout); + + _LOGD(ping_op->log_domain, + "ping: ip-ping-addresses requires any, one ping check on ip-ping-addresses " + "succeeded"); + ip_check_pre_up(self); + } } else { /* If ping exited with an error it may have returned early, * wait 1 second and restart it */ - priv->gw_ping.watch = g_timeout_add_seconds(1, respawn_ping_cb, self); + ping_op->watch = nm_g_timeout_add_seconds_source(1, respawn_ping_cb, ping_op); } } @@ -14851,39 +15166,31 @@ ip_check_ping_timeout_cb(gpointer user_data) NMDevice *self = NM_DEVICE(user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - priv->gw_ping.timeout = 0; + _LOGW(LOGD_DEVICE, "ping timeout: unreachable gateway or ip-ping-addresses"); - _LOGW(priv->gw_ping.log_domain, "ping: gateway ping timed out"); + if (priv->ping_operations) { + g_list_free_full(priv->ping_operations, (GDestroyNotify) cleanup_ping_operation); + priv->ping_operations = NULL; + } - ip_check_gw_ping_cleanup(self); + if (priv->ping_timeout) + nm_clear_g_source_inst(&priv->ping_timeout); ip_check_pre_up(self); + return FALSE; } static gboolean -start_ping(NMDevice *self, - NMLogDomain log_domain, - const char *binary, - const char *address, - guint timeout) +start_ping(NMDevice *self, PingOperation *ping_op) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - g_return_val_if_fail(priv->gw_ping.watch == 0, FALSE); - g_return_val_if_fail(priv->gw_ping.timeout == 0, FALSE); - - priv->gw_ping.log_domain = log_domain; - priv->gw_ping.address = g_strdup(address); - priv->gw_ping.binary = g_strdup(binary); - priv->gw_ping.deadline = timeout + 10; /* the proper termination is enforced by a timer */ - - if (spawn_ping(self)) { - priv->gw_ping.watch = g_child_watch_add(priv->gw_ping.pid, ip_check_ping_watch_cb, self); - priv->gw_ping.timeout = g_timeout_add_seconds(timeout, ip_check_ping_timeout_cb, self); + if (spawn_ping_for_operation(self, ping_op)) { + priv->ping_operations = g_list_append(priv->ping_operations, ping_op); return TRUE; } - ip_check_gw_ping_cleanup(self); + cleanup_ping_operation(ping_op); return FALSE; } @@ -14893,18 +15200,19 @@ nm_device_start_ip_check(NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); NMConnection *connection; NMSettingConnection *s_con; - guint timeout = 0; - const char *ping_binary = NULL; + guint gw_ping_timeout = 0; + guint ip_ping_timeout = 0; + const char *ping_binary = NULL; char buf[NM_INET_ADDRSTRLEN]; NMLogDomain log_domain = LOGD_IP4; + gboolean ip_ping_addresses_require_all; + gboolean ping_started = FALSE; /* Shouldn't be any active ping here, since IP_CHECK happens after the * first IP method completes. Any subsequently completing IP method doesn't * get checked. */ - g_return_if_fail(!priv->gw_ping.watch); - g_return_if_fail(!priv->gw_ping.timeout); - g_return_if_fail(!priv->gw_ping.pid); + g_return_if_fail(priv->ping_operations == NULL); g_return_if_fail(priv->ip_data_4.state == NM_DEVICE_IP_STATE_READY || priv->ip_data_6.state == NM_DEVICE_IP_STATE_READY); @@ -14913,13 +15221,17 @@ nm_device_start_ip_check(NMDevice *self) s_con = nm_connection_get_setting_connection(connection); g_assert(s_con); - timeout = nm_setting_connection_get_gateway_ping_timeout(s_con); + gw_ping_timeout = nm_setting_connection_get_gateway_ping_timeout(s_con); + ip_ping_addresses_require_all = _prop_get_connection_ip_ping_addresses_require_all(self, s_con); + ip_ping_timeout = nm_setting_connection_get_ip_ping_timeout(s_con); buf[0] = '\0'; - if (timeout) { + if (gw_ping_timeout != 0 && ip_ping_timeout == 0) { const NMPObject *gw; const NML3ConfigData *l3cd; + _LOGD(LOGD_DEVICE, "starting ping gateway..."); + l3cd = priv->l3cfg ? nm_l3cfg_get_combined_l3cd(priv->l3cfg, TRUE) : NULL; if (!l3cd) { /* pass */ @@ -14940,11 +15252,68 @@ nm_device_start_ip_check(NMDevice *self) } } - if (buf[0]) - start_ping(self, log_domain, ping_binary, buf, timeout); + if (buf[0]) { + PingOperation *ping_op = ping_operation_new(self, + log_domain, + buf, + ping_binary, + gw_ping_timeout, + ip_ping_addresses_require_all); - /* If no ping was started, just advance to pre_up */ - if (!priv->gw_ping.pid) + if (start_ping(self, ping_op)) + ping_started = TRUE; + } + + if (gw_ping_timeout == 0 && ip_ping_timeout != 0) { + const NML3ConfigData *l3cd; + guint i; + GArray *ip_ping_addresses = _nm_setting_connection_get_ip_ping_addresses(s_con); + const char *const *strv = nm_strvarray_get_strv_notempty(ip_ping_addresses, NULL); + + _LOGD(LOGD_DEVICE, "starting ping ip addresses..."); + + l3cd = priv->l3cfg ? nm_l3cfg_get_combined_l3cd(priv->l3cfg, TRUE) : NULL; + + if (l3cd) { + for (i = 0; strv[i]; i++) { + const char *s = strv[i]; + struct in_addr ipv4_addr; + struct in6_addr ipv6_addr; + + if (priv->ip_data_4.state == NM_DEVICE_IP_STATE_READY + && inet_pton(AF_INET, (const char *) s, &ipv4_addr)) { + ping_binary = nm_utils_find_helper("ping", "/usr/bin/ping", NULL); + log_domain = LOGD_IP4; + } else if (priv->ip_data_6.state == NM_DEVICE_IP_STATE_READY + && inet_pton(AF_INET6, (const char *) s, &ipv6_addr)) { + ping_binary = nm_utils_find_helper("ping6", "/usr/bin/ping6", NULL); + log_domain = LOGD_IP6; + } else + continue; + + if (s[0]) { + PingOperation *ping_op = ping_operation_new(self, + log_domain, + s, + ping_binary, + ip_ping_timeout, + ip_ping_addresses_require_all); + + if (start_ping(self, ping_op)) + ping_started = TRUE; + } + } + } + } + + if (ping_started) { + priv->ping_timeout = + nm_g_timeout_add_seconds_source(gw_ping_timeout ? gw_ping_timeout : ip_ping_timeout, + ip_check_ping_timeout_cb, + self); + } + /* If no ping was started, just advance to pre_up. */ + else ip_check_pre_up(self); } @@ -16403,7 +16772,14 @@ _cancel_activation(NMDevice *self) } _dispatcher_cleanup(self); - ip_check_gw_ping_cleanup(self); + + if (priv->ping_operations) { + g_list_free_full(priv->ping_operations, (GDestroyNotify) cleanup_ping_operation); + priv->ping_operations = NULL; + } + + if (priv->ping_timeout) + nm_clear_g_source_inst(&priv->ping_timeout); _dev_ip_state_cleanup(self, AF_INET, FALSE); _dev_ip_state_cleanup(self, AF_INET6, FALSE); @@ -16629,6 +17005,9 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu priv->promisc_reset = NM_OPTION_BOOL_DEFAULT; } + priv->ipv4_method = NULL; + priv->ipv6_method = NULL; + _cleanup_generic_post(self, reason, cleanup_type); } @@ -16643,6 +17022,9 @@ deactivate_reset_hw_addr(NMDevice *self) static void ip6_managed_setup(NMDevice *self) { + if (!g_file_test("/proc/sys/net/ipv6", G_FILE_TEST_IS_DIR)) + return; + _dev_addrgenmode6_set(self, NM_IN6_ADDR_GEN_MODE_NONE); _dev_sysctl_set_disable_ipv6(self, FALSE); nm_device_sysctl_ip_conf_set(self, AF_INET6, "accept_ra", "0"); @@ -17138,7 +17520,12 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, break; } case NM_DEVICE_STATE_SECONDARIES: - ip_check_gw_ping_cleanup(self); + if (priv->ping_operations) { + g_list_free_full(priv->ping_operations, (GDestroyNotify) cleanup_ping_operation); + priv->ping_operations = NULL; + } + if (priv->ping_timeout) + nm_clear_g_source_inst(&priv->ping_timeout); _LOGD(LOGD_DEVICE, "device entered SECONDARIES state"); break; default: @@ -18382,7 +18769,7 @@ nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean resolver = priv->hostname_resolver_x[IS_IPv4]; if (!resolver) { resolver = g_slice_new(HostnameResolver); - *resolver = (HostnameResolver){ + *resolver = (HostnameResolver) { .device = self, .addr_family = addr_family, .state = RESOLVER_WAIT_ADDRESS, @@ -18737,7 +19124,7 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps nm_assert(priv->type == NM_DEVICE_TYPE_UNKNOWN); priv->type = g_value_get_uint(value); nm_assert(priv->type > NM_DEVICE_TYPE_UNKNOWN); - nm_assert(priv->type <= NM_DEVICE_TYPE_HSR); + nm_assert(priv->type <= NM_DEVICE_TYPE_IPVLAN); break; case PROP_LINK_TYPE: /* construct-only */ @@ -19525,6 +19912,9 @@ nm_device_class_init(NMDeviceClass *klass) G_TYPE_BOOLEAN, 0); + /* Signal "l3cd-changed" indicates that the combined layer-3 configuration + * on the device has changed. It is invoked after the new configuration has + * been committed to kernel. */ signals[L3CD_CHANGED] = g_signal_new(NM_DEVICE_L3CD_CHANGED, G_OBJECT_CLASS_TYPE(object_class), G_SIGNAL_RUN_FIRST, diff --git a/src/core/devices/nm-lldp-listener.c b/src/core/devices/nm-lldp-listener.c index 59c8f54c..e08b379a 100644 --- a/src/core/devices/nm-lldp-listener.c +++ b/src/core/devices/nm-lldp-listener.c @@ -397,7 +397,7 @@ lldp_neighbor_new(NMLldpNeighbor *neighbor_nm) } neigh = g_slice_new(LldpNeighbor); - *neigh = (LldpNeighbor){ + *neigh = (LldpNeighbor) { .neighbor_nm = nm_lldp_neighbor_ref(neighbor_nm), .chassis_id_type = chassis_id_type, .chassis_id = g_steal_pointer(&s_chassis_id), @@ -522,7 +522,7 @@ lldp_neighbor_to_variant(LldpNeighbor *neigh) if (len <= 6) continue; - /* skip over leading TLV, OUI and subtype */ + /* skip over leading TLV, OUI and subtype */ #if NM_MORE_ASSERTS > 5 { guint8 check_hdr[] = {0xfe | (((len - 2) >> 8) & 0x01), @@ -721,7 +721,7 @@ nmtst_lldp_parse_from_raw(const guint8 *raw_data, gsize raw_len) g_assert(raw_data); g_assert(raw_len > 0); - lldp_rx = nm_lldp_rx_new(&((NMLldpRXConfig){ + lldp_rx = nm_lldp_rx_new(&((NMLldpRXConfig) { .ifindex = 1, .neighbors_max = MAX_NEIGHBORS, .callback = nmtst_lldp_event_handler, @@ -889,7 +889,7 @@ nm_lldp_listener_new(int ifindex, g_return_val_if_fail(notify_callback, FALSE); self = g_slice_new(NMLldpListener); - *self = (NMLldpListener){ + *self = (NMLldpListener) { .ifindex = ifindex, .notify_callback = notify_callback, .notify_user_data = notify_user_data, @@ -897,7 +897,7 @@ nm_lldp_listener_new(int ifindex, nm_assert(nm_g_main_context_is_thread_default(g_main_context_default())); - lldp_rx = nm_lldp_rx_new(&((NMLldpRXConfig){ + lldp_rx = nm_lldp_rx_new(&((NMLldpRXConfig) { .ifindex = ifindex, .neighbors_max = MAX_NEIGHBORS, .callback = lldp_event_handler, diff --git a/src/core/devices/ovs/nm-device-ovs-interface.c b/src/core/devices/ovs/nm-device-ovs-interface.c index 8aeb8718..06a1da15 100644 --- a/src/core/devices/ovs/nm-device-ovs-interface.c +++ b/src/core/devices/ovs/nm-device-ovs-interface.c @@ -603,7 +603,7 @@ deactivate_async(NMDevice *device, * with a timeout. */ data = g_slice_new(DeactivateData); - *data = (DeactivateData){ + *data = (DeactivateData) { .self = g_object_ref(self), .cancellable = g_object_ref(cancellable), .callback = callback, diff --git a/src/core/devices/ovs/nm-device-ovs-port.c b/src/core/devices/ovs/nm-device-ovs-port.c index 2e8ab717..7eacedb8 100644 --- a/src/core/devices/ovs/nm-device-ovs-port.c +++ b/src/core/devices/ovs/nm-device-ovs-port.c @@ -175,7 +175,7 @@ attach_port(NMDevice *device, } data = g_slice_new(AttachPortData); - *data = (AttachPortData){ + *data = (AttachPortData) { .device = g_object_ref(device), .port = g_object_ref(port), .cancellable = g_object_ref(cancellable), @@ -233,7 +233,7 @@ detach_port(NMDevice *device, AttachPortData *data; data = g_slice_new(AttachPortData); - *data = (AttachPortData){ + *data = (AttachPortData) { .device = g_object_ref(device), .port = g_object_ref(port), .cancellable = nm_g_object_ref(cancellable), diff --git a/src/core/devices/ovs/nm-ovsdb.c b/src/core/devices/ovs/nm-ovsdb.c index 8e32cff5..528d44d8 100644 --- a/src/core/devices/ovs/nm-ovsdb.c +++ b/src/core/devices/ovs/nm-ovsdb.c @@ -205,7 +205,7 @@ static void cleanup_check_ready(NMOvsdb *self); /*****************************************************************************/ #define OVSDB_METHOD_PAYLOAD_MONITOR() \ - (&((const OvsdbMethodPayload){ \ + (&((const OvsdbMethodPayload) { \ .monitor = {}, \ })) @@ -214,7 +214,7 @@ static void cleanup_check_ready(NMOvsdb *self); xinterface, \ xbridge_device, \ xinterface_device) \ - (&((const OvsdbMethodPayload){ \ + (&((const OvsdbMethodPayload) { \ .add_interface = \ { \ .bridge = (xbridge), \ @@ -226,7 +226,7 @@ static void cleanup_check_ready(NMOvsdb *self); })) #define OVSDB_METHOD_PAYLOAD_DEL_INTERFACE(xifname) \ - (&((const OvsdbMethodPayload){ \ + (&((const OvsdbMethodPayload) { \ .del_interface = \ { \ .ifname = (char *) NM_CONSTCAST(char, (xifname)), \ @@ -234,7 +234,7 @@ static void cleanup_check_ready(NMOvsdb *self); })) #define OVSDB_METHOD_PAYLOAD_SET_INTERFACE_MTU(xifname, xmtu) \ - (&((const OvsdbMethodPayload){ \ + (&((const OvsdbMethodPayload) { \ .set_interface_mtu = \ { \ .ifname = (char *) NM_CONSTCAST(char, (xifname)), \ @@ -249,7 +249,7 @@ static void cleanup_check_ready(NMOvsdb *self); xexternal_ids_new, \ xother_config_old, \ xother_config_new) \ - (&((const OvsdbMethodPayload){ \ + (&((const OvsdbMethodPayload) { \ .set_reapply = \ { \ .device_type = xdevice_type, \ @@ -420,7 +420,7 @@ ovsdb_call_method(NMOvsdb *self, ovsdb_try_connect(self); call = g_slice_new(OvsdbMethodCall); - *call = (OvsdbMethodCall){ + *call = (OvsdbMethodCall) { .self = self, .call_id = CALL_ID_UNSPEC, .command = command, @@ -1682,7 +1682,7 @@ _strdict_extract(json_t *strdict, GArray **out_array) } v = nm_g_array_append_new(*out_array, NMUtilsNamedValue); - *v = (NMUtilsNamedValue){ + *v = (NMUtilsNamedValue) { .name = g_strdup(key), .value_str = g_strdup(val), }; @@ -1909,7 +1909,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) gs_free char *strtmp2 = NULL; ovs_interface = g_slice_new(OpenvswitchInterface); - *ovs_interface = (OpenvswitchInterface){ + *ovs_interface = (OpenvswitchInterface) { .interface_uuid = g_strdup(key), .name = g_strdup(name), .type = g_strdup(type), @@ -2040,7 +2040,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) gs_free char *strtmp2 = NULL; ovs_port = g_slice_new(OpenvswitchPort); - *ovs_port = (OpenvswitchPort){ + *ovs_port = (OpenvswitchPort) { .port_uuid = g_strdup(key), .name = g_strdup(name), .connection_uuid = g_strdup(connection_uuid), @@ -2161,7 +2161,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) gs_free char *strtmp2 = NULL; ovs_bridge = g_slice_new(OpenvswitchBridge); - *ovs_bridge = (OpenvswitchBridge){ + *ovs_bridge = (OpenvswitchBridge) { .bridge_uuid = g_strdup(key), .name = g_strdup(name), .connection_uuid = g_strdup(connection_uuid), @@ -2905,7 +2905,7 @@ ovsdb_call_new(NMOvsdbCallback callback, gpointer user_data) OvsdbCall *call; call = g_slice_new(OvsdbCall); - *call = (OvsdbCall){ + *call = (OvsdbCall) { .callback = callback, .user_data = user_data, }; diff --git a/src/core/devices/team/nm-device-team.c b/src/core/devices/team/nm-device-team.c index a4c77f7f..40779c89 100644 --- a/src/core/devices/team/nm-device-team.c +++ b/src/core/devices/team/nm-device-team.c @@ -130,8 +130,7 @@ complete_connection(NMDevice *device, NULL, _("Team connection"), "team", - NULL, - TRUE); + NULL); _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_TEAM); diff --git a/src/core/devices/wifi/nm-device-iwd-p2p.c b/src/core/devices/wifi/nm-device-iwd-p2p.c index fadc6722..184c8ec5 100644 --- a/src/core/devices/wifi/nm-device-iwd-p2p.c +++ b/src/core/devices/wifi/nm-device-iwd-p2p.c @@ -301,8 +301,7 @@ complete_connection(NMDevice *device, setting_name, setting_name, NULL, - NULL, - TRUE); + NULL); return TRUE; } diff --git a/src/core/devices/wifi/nm-device-iwd.c b/src/core/devices/wifi/nm-device-iwd.c index d6e3ed08..fa6e2f9d 100644 --- a/src/core/devices/wifi/nm-device-iwd.c +++ b/src/core/devices/wifi/nm-device-iwd.c @@ -275,7 +275,7 @@ ap_from_network(NMDeviceIwd *self, ssid = g_bytes_new(name, NM_MIN(32u, strlen(name))); - bss_info = (NMSupplicantBssInfo){ + bss_info = (NMSupplicantBssInfo) { .bss_path = bss_path, .last_seen_msec = last_seen_msec, .bssid_valid = TRUE, @@ -1074,8 +1074,7 @@ complete_connection(NMDevice *device, ssid_utf8, ssid_utf8, NULL, - NULL, - TRUE); + NULL); if (hidden) g_object_set(s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); @@ -3602,7 +3601,7 @@ nm_device_iwd_parse_netconfig(NMDeviceIwd *self, int addr_family, GVariantIter * preferred_lifetime = valid_lifetime; if (addr_family == AF_INET) { - a.a4 = (NMPlatformIP4Address){ + a.a4 = (NMPlatformIP4Address) { .address = addr_bin.addr4, .peer_address = addr_bin.addr4, .plen = plen, @@ -3614,7 +3613,7 @@ nm_device_iwd_parse_netconfig(NMDeviceIwd *self, int addr_family, GVariantIter * .broadcast_address = bcast_bin.addr4, }; } else { - a.a6 = (NMPlatformIP6Address){ + a.a6 = (NMPlatformIP6Address) { .address = addr_bin.addr6, .plen = 128, .timestamp = (valid_lifetime != NM_PLATFORM_LIFETIME_PERMANENT) ? timestamp : 0, @@ -3703,7 +3702,7 @@ nm_device_iwd_parse_netconfig(NMDeviceIwd *self, int addr_family, GVariantIter * } if (addr_family == AF_INET) { - r.r4 = (NMPlatformIP4Route){ + r.r4 = (NMPlatformIP4Route) { .network = dst_addr_str ? dst_addr_bin.addr4 : 0, .plen = dst_addr_str ? dst_plen : 0, .gateway = router_str ? router_bin.addr4 : 0, @@ -3712,7 +3711,7 @@ nm_device_iwd_parse_netconfig(NMDeviceIwd *self, int addr_family, GVariantIter * nm_platform_route_scope_inv(router_str ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK), }; } else { - r.r6 = (NMPlatformIP6Route){ + r.r6 = (NMPlatformIP6Route) { .network = dst_addr_str ? dst_addr_bin.addr6 : nm_ip_addr_zero.addr6, .plen = dst_addr_str ? dst_plen : 0, .gateway = router_str ? router_bin.addr6 : nm_ip_addr_zero.addr6, @@ -3739,7 +3738,7 @@ nm_device_iwd_parse_netconfig(NMDeviceIwd *self, int addr_family, GVariantIter * if (inet_pton(addr_family, str_value, &dns_bin) != 1) goto param_error; - nm_l3_config_data_add_nameserver_detail(l3cd, addr_family, &dns_bin, NULL); + nm_l3_config_data_add_nameserver_addr(l3cd, addr_family, &dns_bin); nm_l3_config_data_set_dns_priority(l3cd, addr_family, NM_DNS_PRIORITY_DEFAULT_NORMAL); } } diff --git a/src/core/devices/wifi/nm-device-olpc-mesh.c b/src/core/devices/wifi/nm-device-olpc-mesh.c index 8e1e779b..b62dc311 100644 --- a/src/core/devices/wifi/nm-device-olpc-mesh.c +++ b/src/core/devices/wifi/nm-device-olpc-mesh.c @@ -111,8 +111,7 @@ complete_connection(NMDevice *device, NULL, _("Mesh"), NULL, - NULL, - FALSE); /* No IPv6 by default */ + NULL); return TRUE; } diff --git a/src/core/devices/wifi/nm-device-wifi-p2p.c b/src/core/devices/wifi/nm-device-wifi-p2p.c index f06383b1..957a2df6 100644 --- a/src/core/devices/wifi/nm-device-wifi-p2p.c +++ b/src/core/devices/wifi/nm-device-wifi-p2p.c @@ -319,8 +319,7 @@ complete_connection(NMDevice *device, setting_name, setting_name, NULL, - NULL, - TRUE); + NULL); return TRUE; } diff --git a/src/core/devices/wifi/nm-device-wifi.c b/src/core/devices/wifi/nm-device-wifi.c index ea65499e..06eee142 100644 --- a/src/core/devices/wifi/nm-device-wifi.c +++ b/src/core/devices/wifi/nm-device-wifi.c @@ -340,7 +340,7 @@ _scan_request_ssids_track(NMDeviceWifiPrivate *priv, const GPtrArray *ssids) d = g_hash_table_lookup(priv->scan_request_ssids_hash, &ssid); if (!d) { d = g_slice_new(ScanRequestSsidData); - *d = (ScanRequestSsidData){ + *d = (ScanRequestSsidData) { .lst = C_LIST_INIT(d->lst), .timestamp_msec = now_msec, .ssid = g_bytes_ref(ssid), @@ -1296,8 +1296,7 @@ complete_connection(NMDevice *device, ssid_utf8, ssid_utf8, NULL, - nm_setting_wireless_get_mac_address(s_wifi) ? NULL : nm_device_get_iface(device), - TRUE); + nm_setting_wireless_get_mac_address(s_wifi) ? NULL : nm_device_get_iface(device)); if (hidden) g_object_set(s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); diff --git a/src/core/devices/wifi/nm-wifi-utils.c b/src/core/devices/wifi/nm-wifi-utils.c index 8a8d062f..332352ab 100644 --- a/src/core/devices/wifi/nm-wifi-utils.c +++ b/src/core/devices/wifi/nm-wifi-utils.c @@ -1577,19 +1577,17 @@ ip_config_to_iwd_config(int addr_family, GKeyFile *file, NMSettingIPConfig *s_ip if (num) { nm_str_buf_reset(&strbuf); for (i = 0; i < num; i++) { - char sbuf[NM_INET_ADDRSTRLEN]; - NMIPAddr a; - - if (!nm_utils_dnsname_parse_assert(addr_family, - nm_setting_ip_config_get_dns(s_ip, i), - NULL, - &a, - NULL)) + char addrstr[NM_INET_ADDRSTRLEN]; + + if (!nm_dns_uri_parse_plain(addr_family, + nm_setting_ip_config_get_dns(s_ip, i), + addrstr, + NULL)) continue; if (strbuf.len > 0) nm_str_buf_append_c(&strbuf, ' '); - nm_str_buf_append(&strbuf, nm_inet_ntop(addr_family, &a, sbuf)); + nm_str_buf_append(&strbuf, addrstr); } /* It doesn't matter whether we add the DNS under [IPv4] or [IPv6] * except that with method=auto the list will override the diff --git a/src/core/devices/wwan/nm-modem-broadband.c b/src/core/devices/wwan/nm-modem-broadband.c index c03446b9..018e5306 100644 --- a/src/core/devices/wwan/nm-modem-broadband.c +++ b/src/core/devices/wwan/nm-modem-broadband.c @@ -668,6 +668,8 @@ connect_context_step(NMModemBroadband *self) NMSettingGsm *s_gsm = nm_connection_get_setting_gsm(ctx->connection); const char *apn = nm_setting_gsm_get_initial_eps_apn(s_gsm); gboolean do_config = nm_setting_gsm_get_initial_eps_config(s_gsm); + const char *username = nm_setting_gsm_get_initial_eps_username(s_gsm); + const char *password = nm_setting_gsm_get_initial_eps_password(s_gsm); /* assume do_config is true if an APN is set */ if (apn || do_config) { @@ -690,9 +692,28 @@ connect_context_step(NMModemBroadband *self) /* do nothing */ break; } - if (apn) - mm_bearer_properties_set_apn(config, apn); + if (apn) { + MMBearerAllowedAuth allowed_auth = MM_BEARER_ALLOWED_AUTH_UNKNOWN; + mm_bearer_properties_set_apn(config, apn); + mm_bearer_properties_set_user(config, username); + mm_bearer_properties_set_password(config, password); + + if (nm_setting_gsm_get_initial_eps_noauth(s_gsm)) + allowed_auth |= MM_BEARER_ALLOWED_AUTH_NONE; + if (!nm_setting_gsm_get_initial_eps_refuse_pap(s_gsm)) + allowed_auth |= MM_BEARER_ALLOWED_AUTH_PAP; + if (!nm_setting_gsm_get_initial_eps_refuse_chap(s_gsm)) + allowed_auth |= MM_BEARER_ALLOWED_AUTH_CHAP; + if (!nm_setting_gsm_get_initial_eps_refuse_mschap(s_gsm)) + allowed_auth |= MM_BEARER_ALLOWED_AUTH_MSCHAP; + if (!nm_setting_gsm_get_initial_eps_refuse_mschapv2(s_gsm)) + allowed_auth |= MM_BEARER_ALLOWED_AUTH_MSCHAPV2; + if (!nm_setting_gsm_get_initial_eps_refuse_eap(s_gsm)) + allowed_auth |= MM_BEARER_ALLOWED_AUTH_EAP; + + mm_bearer_properties_set_allowed_auth(config, allowed_auth); + } /* * Setting the initial EPS bearer settings is a no-op in * ModemManager if the desired configuration is already active. @@ -896,8 +917,7 @@ complete_connection(NMModem *modem, NULL, _("GSM connection"), NULL, - NULL, - FALSE); /* No IPv6 yet by default */ + NULL); return TRUE; } @@ -917,8 +937,7 @@ complete_connection(NMModem *modem, NULL, _("CDMA connection"), NULL, - iface, - FALSE); /* No IPv6 yet by default */ + iface); return TRUE; } @@ -1116,7 +1135,7 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho ifindex, NM_IP_CONFIG_SOURCE_WWAN); - address = (NMPlatformIP4Address){ + address = (NMPlatformIP4Address) { .address = address_network, .peer_address = address_network, .plen = mm_bearer_ip_config_get_prefix(self->_priv.ipv4_config), @@ -1127,7 +1146,7 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho _LOGI(" address %s", nm_platform_ip4_address_to_string(&address, sbuf, sizeof(sbuf))); - route = (NMPlatformIP4Route){ + route = (NMPlatformIP4Route) { .rt_source = NM_IP_CONFIG_SOURCE_WWAN, .gateway = gw, .table_any = TRUE, @@ -1141,7 +1160,7 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho dns = mm_bearer_ip_config_get_dns(self->_priv.ipv4_config); for (i = 0; dns && dns[i]; i++) { if (nm_inet_parse_bin(AF_INET, dns[i], NULL, &address_network) && address_network > 0) { - nm_l3_config_data_add_nameserver_detail(l3cd, AF_INET, &address_network, NULL); + nm_l3_config_data_add_nameserver_addr(l3cd, AF_INET, &address_network); _LOGI(" DNS %s", dns[i]); } } @@ -1193,7 +1212,7 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho do_auto = TRUE; if (address_string) { - address = (NMPlatformIP6Address){}; + address = (NMPlatformIP6Address) {}; if (!inet_pton(AF_INET6, address_string, &address.address)) { g_set_error(&error, @@ -1260,7 +1279,7 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho struct in6_addr addr; if (inet_pton(AF_INET6, dns[i], &addr)) { - nm_l3_config_data_add_nameserver_detail(l3cd, AF_INET6, &addr, NULL); + nm_l3_config_data_add_nameserver_addr(l3cd, AF_INET6, &addr); _LOGI(" DNS %s", dns[i]); } } diff --git a/src/core/devices/wwan/nm-modem-ofono.c b/src/core/devices/wwan/nm-modem-ofono.c index 3e0bbd48..80f966f1 100644 --- a/src/core/devices/wwan/nm-modem-ofono.c +++ b/src/core/devices/wwan/nm-modem-ofono.c @@ -1256,7 +1256,7 @@ handle_settings(NMModemOfono *self, GVariant *v_dict) goto out; } - address = (NMPlatformIP4Address){ + address = (NMPlatformIP4Address) { .ifindex = ifindex, .address = address_network, .addr_source = NM_IP_CONFIG_SOURCE_WWAN, @@ -1315,7 +1315,7 @@ handle_settings(NMModemOfono *self, GVariant *v_dict) } any_good = TRUE; _LOGI("DNS: %s", array[i]); - nm_l3_config_data_add_nameserver_detail(priv->l3cd_4, AF_INET, &address_network, NULL); + nm_l3_config_data_add_nameserver_addr(priv->l3cd_4, AF_INET, &address_network); } if (!any_good) { _LOGW("Settings: 'DomainNameServers': none specified"); diff --git a/src/core/devices/wwan/nm-modem.c b/src/core/devices/wwan/nm-modem.c index 23e7de4a..c4852ea2 100644 --- a/src/core/devices/wwan/nm-modem.c +++ b/src/core/devices/wwan/nm-modem.c @@ -1064,7 +1064,7 @@ nm_modem_act_stage2_config(NMModem *self, NMDevice *device, NMDeviceStateReason else baud_override = 0; - priv->ppp_mgr = nm_ppp_mgr_start(&((const NMPppMgrConfig){ + priv->ppp_mgr = nm_ppp_mgr_start(&((const NMPppMgrConfig) { .netns = nm_device_get_netns(device), .parent_iface = priv->data_port, .callback = _ppp_mgr_callback, diff --git a/src/core/dhcp/nm-dhcp-client.c b/src/core/dhcp/nm-dhcp-client.c index cd6e67e2..18ad4024 100644 --- a/src/core/dhcp/nm-dhcp-client.c +++ b/src/core/dhcp/nm-dhcp-client.c @@ -91,6 +91,11 @@ typedef struct _NMDhcpClientPrivate { union { struct { + /* Timer for restarting DHCP after the IPv6-only timeout */ + GSource *ipv6_only_restart_source; + /* Minimum value accepted for the IPv6-only option. For test/debug only.*/ + guint ipv6_only_min_wait; + struct { NML3CfgCommitTypeHandle *l3cfg_commit_handle; GSource *done_source; @@ -336,7 +341,7 @@ _emit_notify_data(NMDhcpClient *self, const NMDhcpClientNotifyData *notify_data) #define _emit_notify(self, _notify_type, ...) \ _emit_notify_data( \ (self), \ - &((const NMDhcpClientNotifyData){.notify_type = (_notify_type), __VA_ARGS__})) + &((const NMDhcpClientNotifyData) {.notify_type = (_notify_type), __VA_ARGS__})) /*****************************************************************************/ @@ -684,7 +689,7 @@ _acd_check_lease(NMDhcpClient *self, NMOptionBool *out_acd_state) now_msec = nm_utils_get_monotonic_timestamp_msec(); g_array_append_val(priv->v4.acd.reglist, - ((AcdRegListData){ + ((AcdRegListData) { .l3cd = nm_l3_config_data_ref(priv->l3cd_next), .addr = addr, .expiry_msec = now_msec + ACD_REGLIST_GRACE_PERIOD_MSEC, @@ -1375,6 +1380,8 @@ nm_dhcp_client_start(NMDhcpClient *self, GError **error) g_return_val_if_fail(priv->config.uuid, FALSE); nm_assert(!priv->effective_client_id); + priv->is_stopped = FALSE; + IS_IPv4 = NM_IS_IPv4(priv->config.addr_family); if (!IS_IPv4) { @@ -1416,6 +1423,51 @@ nm_dhcp_client_start(NMDhcpClient *self, GError **error) /*****************************************************************************/ +static gboolean +ipv6_only_restart_timeout_cb(gpointer user_data) +{ + NMDhcpClient *self = user_data; + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self); + gs_free_error GError *error = NULL; + + nm_assert(priv->config.addr_family == AF_INET); + + nm_clear_g_source_inst(&priv->v4.ipv6_only_restart_source); + if (!nm_dhcp_client_start(self, &error)) { + _LOGW("failed to restart the DHCP client after the IPv6-only timeout: %s", error->message); + _emit_notify(self, + NM_DHCP_CLIENT_NOTIFY_TYPE_IT_LOOKS_BAD, + .it_looks_bad.reason = error->message); + } + + return G_SOURCE_CONTINUE; +} + +/** + * nm_dhcp_client_schedule_ipv6_only_restart(): + * @self: the client + * @timeout: the raw value from the DHCP option + * + * Stops the DHCPv4 client and restarts it after the timeout announced + * by the "IPv6-Only preferred" option. + */ +void +nm_dhcp_client_schedule_ipv6_only_restart(NMDhcpClient *self, guint timeout) +{ + NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self); + + nm_assert(priv->config.addr_family == AF_INET); + nm_assert(!priv->is_stopped); + + timeout = NM_MAX(priv->v4.ipv6_only_min_wait, timeout); + _LOGI("received option \"ipv6-only-preferred\": stopping DHCPv4 for %u seconds", timeout); + + nm_dhcp_client_stop(self, FALSE); + nm_clear_g_source_inst(&priv->no_lease_timeout_source); + priv->v4.ipv6_only_restart_source = + nm_g_timeout_add_seconds_source(timeout, ipv6_only_restart_timeout_cb, self); +} + void nm_dhcp_client_stop_existing(const char *pid_file, const char *binary_name) { @@ -1488,7 +1540,10 @@ nm_dhcp_client_stop(NMDhcpClient *self, gboolean release) if (priv->is_stopped) return; + nm_clear_pointer(&priv->effective_client_id, g_bytes_unref); nm_clear_g_source_inst(&priv->previous_lease_timeout_source); + if (priv->config.addr_family == AF_INET) + nm_clear_g_source_inst(&priv->v4.ipv6_only_restart_source); priv->is_stopped = TRUE; @@ -1934,6 +1989,8 @@ static void set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(object); + const char *str; + guint min_wait; switch (prop_id) { case PROP_CONFIG: @@ -1943,7 +2000,8 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps /* I know, this is technically not necessary. It just feels nicer to * explicitly initialize the respective union member. */ if (NM_IS_IPv4(priv->config.addr_family)) { - priv->v4 = (typeof(priv->v4)){ + priv->v4 = (typeof(priv->v4)) { + .ipv6_only_min_wait = NM_DHCP_MIN_V6ONLY_WAIT_DEFAULT, .acd = { .addr = INADDR_ANY, @@ -1952,8 +2010,16 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps .done_source = NULL, }, }; + + str = g_getenv("NM_TEST_IPV6_ONLY_MIN_WAIT"); + if (str) { + min_wait = _nm_utils_ascii_str_to_int64(str, 10, 1, G_MAXUINT, 0); + if (min_wait != 0) { + priv->v4.ipv6_only_min_wait = min_wait; + } + } } else { - priv->v6 = (typeof(priv->v6)){ + priv->v6 = (typeof(priv->v6)) { .lladdr_timeout_source = NULL, }; } @@ -1990,13 +2056,13 @@ dispose(GObject *object) nm_clear_g_source_inst(&priv->previous_lease_timeout_source); nm_clear_g_source_inst(&priv->no_lease_timeout_source); - if (!NM_IS_IPv4(priv->config.addr_family)) { + if (priv->config.addr_family == AF_INET) { + nm_clear_g_source_inst(&priv->v4.ipv6_only_restart_source); + } else { nm_clear_g_source_inst(&priv->v6.lladdr_timeout_source); nm_clear_g_source_inst(&priv->v6.dad_timeout_source); } - nm_clear_pointer(&priv->effective_client_id, g_bytes_unref); - nm_assert(!priv->watch_source); nm_assert(!priv->l3cd_next); nm_assert(!priv->l3cd_curr); diff --git a/src/core/dhcp/nm-dhcp-client.h b/src/core/dhcp/nm-dhcp-client.h index 8c685faf..a7b6ae98 100644 --- a/src/core/dhcp/nm-dhcp-client.h +++ b/src/core/dhcp/nm-dhcp-client.h @@ -27,6 +27,8 @@ #define NM_DHCP_CLIENT_NOTIFY "dhcp-notify" +#define NM_DHCP_MIN_V6ONLY_WAIT_DEFAULT 300u /* (seconds). RFC 8925, section 3.4 */ + typedef enum { NM_DHCP_CLIENT_EVENT_TYPE_UNSPECIFIED, @@ -172,6 +174,8 @@ typedef struct { /* Whether to send or not the client identifier */ bool send_client_id : 1; + /* Request and honor the "IPv6-only Preferred" option (RFC 8925).*/ + bool ipv6_only_preferred : 1; } v4; struct { /* If set, the DUID from the connection is used; otherwise @@ -246,6 +250,8 @@ const NML3ConfigData *nm_dhcp_client_get_lease(NMDhcpClient *self, gboolean igno void nm_dhcp_client_stop(NMDhcpClient *self, gboolean release); +void nm_dhcp_client_schedule_ipv6_only_restart(NMDhcpClient *self, guint timeout); + /* Backend helpers for subclasses */ void nm_dhcp_client_stop_existing(const char *pid_file, const char *binary_name); @@ -305,7 +311,6 @@ typedef struct { GType nm_dhcp_nettools_get_type(void); -extern const NMDhcpClientFactory _nm_dhcp_client_factory_dhcpcanon; extern const NMDhcpClientFactory _nm_dhcp_client_factory_dhclient; extern const NMDhcpClientFactory _nm_dhcp_client_factory_dhcpcd; extern const NMDhcpClientFactory _nm_dhcp_client_factory_internal; diff --git a/src/core/dhcp/nm-dhcp-dhclient.c b/src/core/dhcp/nm-dhcp-dhclient.c index 043c2264..7e00599c 100644 --- a/src/core/dhcp/nm-dhcp-dhclient.c +++ b/src/core/dhcp/nm-dhcp-dhclient.c @@ -462,6 +462,11 @@ dhclient_start(NMDhcpClient *client, "to LOWDELAY (0x10)."); } + if (client_config->v4.ipv6_only_preferred) { + _LOGW("the dhclient backend does not support the \"IPv6-Only Preferred\" option; ignoring " + "it"); + } + /* Usually the system bus address is well-known; but if it's supposed * to be something else, we need to push it to dhclient, since dhclient * sanitizes the environment it gives the action scripts. diff --git a/src/core/dhcp/nm-dhcp-dhcpcanon.c b/src/core/dhcp/nm-dhcp-dhcpcanon.c deleted file mode 100644 index cd42b692..00000000 --- a/src/core/dhcp/nm-dhcp-dhcpcanon.c +++ /dev/null @@ -1,239 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2017 juga <juga at riseup dot net> - */ - -#include "src/core/nm-default-daemon.h" - -#if WITH_DHCPCANON - -#include <stdlib.h> -#include <unistd.h> - -#include "nm-utils.h" -#include "nm-dhcp-manager.h" -#include "NetworkManagerUtils.h" -#include "nm-dhcp-listener.h" -#include "nm-dhcp-client-logging.h" - -#define NM_TYPE_DHCP_DHCPCANON (nm_dhcp_dhcpcanon_get_type()) -#define NM_DHCP_DHCPCANON(obj) \ - (_NM_G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DHCP_DHCPCANON, NMDhcpDhcpcanon)) -#define NM_DHCP_DHCPCANON_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DHCP_DHCPCANON, NMDhcpDhcpcanonClass)) -#define NM_IS_DHCP_DHCPCANON(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DHCP_DHCPCANON)) -#define NM_IS_DHCP_DHCPCANON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DHCP_DHCPCANON)) -#define NM_DHCP_DHCPCANON_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DHCP_DHCPCANON, NMDhcpDhcpcanonClass)) - -typedef struct _NMDhcpDhcpcanon NMDhcpDhcpcanon; -typedef struct _NMDhcpDhcpcanonClass NMDhcpDhcpcanonClass; - -static GType nm_dhcp_dhcpcanon_get_type(void); - -/*****************************************************************************/ - -typedef struct { - char *conf_file; - const char *def_leasefile; - char *lease_file; - char *pid_file; - NMDhcpListener *dhcp_listener; -} NMDhcpDhcpcanonPrivate; - -struct _NMDhcpDhcpcanon { - NMDhcpClient parent; - NMDhcpDhcpcanonPrivate _priv; -}; - -struct _NMDhcpDhcpcanonClass { - NMDhcpClientClass parent; -}; - -G_DEFINE_TYPE(NMDhcpDhcpcanon, nm_dhcp_dhcpcanon, NM_TYPE_DHCP_CLIENT) - -#define NM_DHCP_DHCPCANON_GET_PRIVATE(self) \ - _NM_GET_PRIVATE(self, NMDhcpDhcpcanon, NM_IS_DHCP_DHCPCANON) - -/*****************************************************************************/ - -static const char * -nm_dhcp_dhcpcanon_get_path(void) -{ - return nm_utils_find_helper("dhcpcanon", DHCPCANON_PATH, NULL); -} - -static gboolean -dhcpcanon_start(NMDhcpClient *client, - const char *mode_opt, - GBytes *duid, - gboolean release, - pid_t *out_pid, - guint needed_prefixes, - GError **error) -{ - NMDhcpDhcpcanon *self = NM_DHCP_DHCPCANON(client); - NMDhcpDhcpcanonPrivate *priv = NM_DHCP_DHCPCANON_GET_PRIVATE(self); - gs_unref_ptrarray GPtrArray *argv = NULL; - pid_t pid; - gs_free_error GError *local = NULL; - const char *iface; - const char *system_bus_address; - const char *dhcpcanon_path; - gs_free char *binary_name = NULL; - gs_free char *pid_file = NULL; - gs_free char *system_bus_address_env = NULL; - int addr_family; - - g_return_val_if_fail(!priv->pid_file, FALSE); - - iface = nm_dhcp_client_get_iface(client); - - addr_family = nm_dhcp_client_get_addr_family(client); - - dhcpcanon_path = nm_dhcp_dhcpcanon_get_path(); - if (!dhcpcanon_path) { - nm_utils_error_set_literal(error, NM_UTILS_ERROR_UNKNOWN, "dhcpcanon binary not found"); - return FALSE; - } - - _LOGD("dhcpcanon_path: %s", dhcpcanon_path); - - pid_file = g_strdup_printf(RUNSTATEDIR "/dhcpcanon%c-%s.pid", - nm_utils_addr_family_to_char(addr_family), - iface); - _LOGD("pid_file: %s", pid_file); - - /* Kill any existing dhcpcanon from the pidfile */ - binary_name = g_path_get_basename(dhcpcanon_path); - nm_dhcp_client_stop_existing(pid_file, binary_name); - - argv = g_ptr_array_new(); - g_ptr_array_add(argv, (gpointer) dhcpcanon_path); - - g_ptr_array_add(argv, (gpointer) "-sf"); /* Set script file */ - g_ptr_array_add(argv, (gpointer) nm_dhcp_helper_path); - - g_ptr_array_add(argv, (gpointer) "-pf"); /* Set pid file */ - g_ptr_array_add(argv, (gpointer) pid_file); - - if (priv->conf_file) { - g_ptr_array_add(argv, (gpointer) "-cf"); /* Set interface config file */ - g_ptr_array_add(argv, (gpointer) priv->conf_file); - } - - /* Usually the system bus address is well-known; but if it's supposed - * to be something else, we need to push it to dhcpcanon, since dhcpcanon - * sanitizes the environment it gives the action scripts. - */ - system_bus_address = getenv("DBUS_SYSTEM_BUS_ADDRESS"); - if (system_bus_address) { - system_bus_address_env = g_strdup_printf("DBUS_SYSTEM_BUS_ADDRESS=%s", system_bus_address); - g_ptr_array_add(argv, (gpointer) "-e"); - g_ptr_array_add(argv, (gpointer) system_bus_address_env); - } - - g_ptr_array_add(argv, (gpointer) iface); - g_ptr_array_add(argv, NULL); - - if (!g_spawn_async(NULL, - (char **) argv->pdata, - NULL, - G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_STDOUT_TO_DEV_NULL - | G_SPAWN_STDERR_TO_DEV_NULL, - nm_utils_setpgid, - NULL, - &pid, - &local)) { - nm_utils_error_set(error, - NM_UTILS_ERROR_UNKNOWN, - "dhcpcanon failed to start: %s", - local->message); - return FALSE; - } - - nm_assert(pid > 0); - _LOGI("dhcpcanon started with pid %d", pid); - nm_dhcp_client_watch_child(client, pid); - priv->pid_file = g_steal_pointer(&pid_file); - return TRUE; -} - -static gboolean -ip4_start(NMDhcpClient *client, GError **error) -{ - return dhcpcanon_start(client, NULL, NULL, FALSE, NULL, 0, error); -} - -static void -stop(NMDhcpClient *client, gboolean release) -{ - NMDhcpDhcpcanon *self = NM_DHCP_DHCPCANON(client); - NMDhcpDhcpcanonPrivate *priv = NM_DHCP_DHCPCANON_GET_PRIVATE(self); - int errsv; - - NM_DHCP_CLIENT_CLASS(nm_dhcp_dhcpcanon_parent_class)->stop(client, release); - - if (priv->pid_file) { - if (remove(priv->pid_file) == -1) { - errsv = errno; - _LOGD("could not remove dhcp pid file \"%s\": %d (%s)", - priv->pid_file, - errsv, - nm_strerror_native(errsv)); - } - g_free(priv->pid_file); - priv->pid_file = NULL; - } -} - -/*****************************************************************************/ - -static void -nm_dhcp_dhcpcanon_init(NMDhcpDhcpcanon *self) -{ - NMDhcpDhcpcanonPrivate *priv = NM_DHCP_DHCPCANON_GET_PRIVATE(self); - - priv->dhcp_listener = g_object_ref(nm_dhcp_listener_get()); - g_signal_connect(priv->dhcp_listener, - NM_DHCP_LISTENER_EVENT, - G_CALLBACK(nm_dhcp_client_handle_event), - self); -} - -static void -dispose(GObject *object) -{ - NMDhcpDhcpcanonPrivate *priv = NM_DHCP_DHCPCANON_GET_PRIVATE(object); - - if (priv->dhcp_listener) { - g_signal_handlers_disconnect_by_func(priv->dhcp_listener, - G_CALLBACK(nm_dhcp_client_handle_event), - NM_DHCP_DHCPCANON(object)); - g_clear_object(&priv->dhcp_listener); - } - - nm_clear_g_free(&priv->pid_file); - - G_OBJECT_CLASS(nm_dhcp_dhcpcanon_parent_class)->dispose(object); -} - -static void -nm_dhcp_dhcpcanon_class_init(NMDhcpDhcpcanonClass *dhcpcanon_class) -{ - NMDhcpClientClass *client_class = NM_DHCP_CLIENT_CLASS(dhcpcanon_class); - GObjectClass *object_class = G_OBJECT_CLASS(dhcpcanon_class); - - object_class->dispose = dispose; - - client_class->ip4_start = ip4_start; - client_class->stop = stop; -} - -const NMDhcpClientFactory _nm_dhcp_client_factory_dhcpcanon = { - .name = "dhcpcanon", - .get_type_4 = nm_dhcp_dhcpcanon_get_type, - .get_path = nm_dhcp_dhcpcanon_get_path, -}; - -#endif /* WITH_DHCPCANON */ diff --git a/src/core/dhcp/nm-dhcp-listener.c b/src/core/dhcp/nm-dhcp-listener.c index 05e428f8..095131cc 100644 --- a/src/core/dhcp/nm-dhcp-listener.c +++ b/src/core/dhcp/nm-dhcp-listener.c @@ -31,9 +31,6 @@ const NMDhcpClientFactory *const _nm_dhcp_manager_factories[6] = { * the first available plugin. */ &_nm_dhcp_client_factory_internal, -#if WITH_DHCPCANON - &_nm_dhcp_client_factory_dhcpcanon, -#endif #if WITH_DHCPCD &_nm_dhcp_client_factory_dhcpcd, #endif diff --git a/src/core/dhcp/nm-dhcp-nettools.c b/src/core/dhcp/nm-dhcp-nettools.c index f4f244c6..27bb136b 100644 --- a/src/core/dhcp/nm-dhcp-nettools.c +++ b/src/core/dhcp/nm-dhcp-nettools.c @@ -169,6 +169,27 @@ lease_option_consume_route(const uint8_t **datap, /*****************************************************************************/ static gboolean +lease_get_ipv6_only_wait_time(NDhcp4ClientLease *lease, guint32 *out_val, const char *iface) +{ + const uint8_t *data; + size_t len; + int r; + + r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_IPV6_ONLY_PREFERRED, &data, &len); + if (r == 0 + && nm_dhcp_lease_data_parse_u32(data, + len, + out_val, + iface, + AF_INET, + NM_DHCP_OPTION_DHCP4_IPV6_ONLY_PREFERRED)) { + return TRUE; + } + + return FALSE; +} + +static gboolean lease_parse_address(NMDhcpNettools *self /* for logging context only */, NDhcp4ClientLease *lease, NML3ConfigData *l3cd, @@ -305,7 +326,7 @@ lease_parse_address(NMDhcpNettools *self /* for logging context only */, } nm_l3_config_data_add_address_4(l3cd, - &((const NMPlatformIP4Address){ + &((const NMPlatformIP4Address) { .address = a_address.s_addr, .peer_address = a_address.s_addr, .plen = a_plen, @@ -366,7 +387,7 @@ lease_parse_address_list(NDhcp4ClientLease *lease, nm_inet4_ntop(addr, addr_str)); continue; } - nm_l3_config_data_add_nameserver_detail(l3cd, AF_INET, &addr, NULL); + nm_l3_config_data_add_nameserver_addr(l3cd, AF_INET, &addr); break; case NM_DHCP_OPTION_DHCP4_NIS_SERVERS: nm_l3_config_data_add_nis_server(l3cd, addr); @@ -445,7 +466,7 @@ lease_parse_routes(NDhcp4ClientLease *lease, m = 0; nm_l3_config_data_add_route_4(l3cd, - &((const NMPlatformIP4Route){ + &((const NMPlatformIP4Route) { .rt_source = NM_IP_CONFIG_SOURCE_DHCP, .network = dest, .plen = plen, @@ -489,7 +510,7 @@ lease_parse_routes(NDhcp4ClientLease *lease, } nm_l3_config_data_add_route_4(l3cd, - &((const NMPlatformIP4Route){ + &((const NMPlatformIP4Route) { .rt_source = NM_IP_CONFIG_SOURCE_DHCP, .network = dest, .plen = plen, @@ -533,7 +554,7 @@ lease_parse_routes(NDhcp4ClientLease *lease, m = default_route_metric_offset++; nm_l3_config_data_add_route_4(l3cd, - &((const NMPlatformIP4Route){ + &((const NMPlatformIP4Route) { .rt_source = NM_IP_CONFIG_SOURCE_DHCP, .gateway = gateway, .pref_src = lease_address, @@ -929,6 +950,22 @@ bound4_handle(NMDhcpNettools *self, guint event, NDhcp4ClientLease *lease) l3cd); } +static gboolean +dhcp4_handle_ipv6_only(NMDhcpNettools *self, NDhcp4ClientEvent *event) +{ + NMDhcpClient *client = NM_DHCP_CLIENT(self); + guint32 val; + + if (nm_dhcp_client_get_config(client)->v4.ipv6_only_preferred + && lease_get_ipv6_only_wait_time(event->offer.lease, + &val, + nm_dhcp_client_get_iface(client))) { + nm_dhcp_client_schedule_ipv6_only_restart(client, val); + return TRUE; + } + return FALSE; +} + static void dhcp4_event_handle(NMDhcpNettools *self, NDhcp4ClientEvent *event) { @@ -962,18 +999,23 @@ dhcp4_event_handle(NMDhcpNettools *self, NDhcp4ClientEvent *event) return; } - n_dhcp4_client_lease_get_yiaddr(event->offer.lease, &yiaddr); - if (yiaddr.s_addr == INADDR_ANY) { - _LOGD("selecting lease failed: no yiaddr address"); - return; - } - if (nm_dhcp_client_server_id_is_rejected(NM_DHCP_CLIENT(self), &server_id)) { _LOGD("server-id %s is in the reject-list, ignoring", nm_inet_ntop(AF_INET, &server_id, addr_str)); return; } + if (dhcp4_handle_ipv6_only(self, event)) + return; + + /* Check yiaddr only after evaluating the ipv6-only-preferred option, because if + * the option is present yiaddr can be zero. */ + n_dhcp4_client_lease_get_yiaddr(event->offer.lease, &yiaddr); + if (yiaddr.s_addr == INADDR_ANY) { + _LOGD("selecting lease failed: no yiaddr address"); + return; + } + if (!_nm_dhcp_client_accept_offer(NM_DHCP_CLIENT(self), &yiaddr.s_addr)) { /* We don't log about this, the parent class is expected to notify about the reasons. */ return; @@ -1001,6 +1043,17 @@ dhcp4_event_handle(NMDhcpNettools *self, NDhcp4ClientEvent *event) _nm_dhcp_client_notify(NM_DHCP_CLIENT(self), NM_DHCP_CLIENT_EVENT_TYPE_FAIL, NULL); return; case N_DHCP4_CLIENT_EVENT_GRANTED: + if (dhcp4_handle_ipv6_only(self, event)) { + /* RFC 8925 says that when the client receives a DHCPACK, it should + * stop the client; but only in the INIT-REBOOT (actually, REBOOTING) + * state, otherwise it should continue to use the address. + * The GRANTED event is emitted both in the REBOOTING and REQUESTING + * state; however if we got the IPv6-only option in the OFFER we have + * already stopped the client. Therefore this point can be reached + * only in the REBOOTING state. + */ + return; + } bound4_handle(self, event->event, event->granted.lease); return; case N_DHCP4_CLIENT_EVENT_EXTENDED: @@ -1323,7 +1376,7 @@ ip4_start(NMDhcpClient *client, GError **error) g_return_val_if_fail(!priv->probe, FALSE); g_return_val_if_fail(client_config, FALSE); - if (!nettools_create(self, &effective_client_id, error)) + if (!priv->client && !nettools_create(self, &effective_client_id, error)) return FALSE; r = n_dhcp4_client_probe_config_new(&config); @@ -1377,6 +1430,11 @@ ip4_start(NMDhcpClient *client, GError **error) } } + if (client_config->v4.ipv6_only_preferred) { + n_dhcp4_client_probe_config_request_option(config, + NM_DHCP_OPTION_DHCP4_IPV6_ONLY_PREFERRED); + } + if (client_config->mud_url) { r = n_dhcp4_client_probe_config_append_option(config, NM_DHCP_OPTION_DHCP4_MUD_URL, diff --git a/src/core/dhcp/nm-dhcp-options.c b/src/core/dhcp/nm-dhcp-options.c index f89237c5..ce03c607 100644 --- a/src/core/dhcp/nm-dhcp-options.c +++ b/src/core/dhcp/nm-dhcp-options.c @@ -113,6 +113,7 @@ const NMDhcpOption _nm_dhcp_option_dhcp4_options[] = { REQ(NM_DHCP_OPTION_DHCP4_PXE_CLIENT_ID, "pxe_client_id", FALSE), REQ(NM_DHCP_OPTION_DHCP4_UAP_SERVERS, "uap_servers", FALSE), REQ(NM_DHCP_OPTION_DHCP4_GEOCONF_CIVIC, "geoconf_civic", FALSE), + REQ(NM_DHCP_OPTION_DHCP4_IPV6_ONLY_PREFERRED, "ipv6_only_preferred", FALSE), REQ(NM_DHCP_OPTION_DHCP4_NETINFO_SERVER_ADDRESS, "netinfo_server_address", FALSE), REQ(NM_DHCP_OPTION_DHCP4_NETINFO_SERVER_TAG, "netinfo_server_tag", FALSE), REQ(NM_DHCP_OPTION_DHCP4_DEFAULT_URL, "default_url", FALSE), @@ -183,11 +184,11 @@ static const NMDhcpOption *const _sorted_options_4[G_N_ELEMENTS(_nm_dhcp_option_ A(13), A(53), A(54), A(55), A(57), A(58), A(59), A(60), A(61), A(62), A(63), A(64), A(65), A(66), A(67), A(68), A(69), A(70), A(71), A(72), A(73), A(74), A(75), A(76), A(77), A(78), A(79), A(80), A(81), A(82), A(83), A(84), A(85), A(86), A(87), A(56), - A(88), A(89), A(90), A(91), A(92), A(93), A(14), A(7), A(94), A(95), A(96), A(97), + A(88), A(89), A(90), A(91), A(92), A(93), A(94), A(14), A(7), A(95), A(96), A(97), A(98), A(99), A(100), A(101), A(102), A(103), A(104), A(105), A(106), A(107), A(108), A(109), A(110), A(111), A(112), A(113), A(114), A(115), A(116), A(117), A(118), A(119), A(120), A(121), A(122), A(123), A(124), A(125), A(126), A(127), A(128), A(129), A(130), A(131), A(132), A(133), - A(134), A(15), A(135), A(136), A(16), A(137), A(138), A(139), A(140), A(141), A(142), + A(134), A(135), A(15), A(136), A(137), A(16), A(138), A(139), A(140), A(141), A(142), A(143), #undef A }; diff --git a/src/core/dhcp/nm-dhcp-options.h b/src/core/dhcp/nm-dhcp-options.h index 1c61c74d..c8ab1dae 100644 --- a/src/core/dhcp/nm-dhcp-options.h +++ b/src/core/dhcp/nm-dhcp-options.h @@ -93,6 +93,7 @@ typedef enum { NM_DHCP_OPTION_DHCP4_UAP_SERVERS = 98, NM_DHCP_OPTION_DHCP4_GEOCONF_CIVIC = 99, NM_DHCP_OPTION_DHCP4_NEW_TZDB_TIMEZONE = 101, + NM_DHCP_OPTION_DHCP4_IPV6_ONLY_PREFERRED = 108, NM_DHCP_OPTION_DHCP4_NETINFO_SERVER_ADDRESS = 112, NM_DHCP_OPTION_DHCP4_NETINFO_SERVER_TAG = 113, NM_DHCP_OPTION_DHCP4_DEFAULT_URL = 114, @@ -188,7 +189,7 @@ typedef struct { bool include; } NMDhcpOption; -extern const NMDhcpOption _nm_dhcp_option_dhcp4_options[143]; +extern const NMDhcpOption _nm_dhcp_option_dhcp4_options[144]; extern const NMDhcpOption _nm_dhcp_option_dhcp6_options[18]; static inline const char * diff --git a/src/core/dhcp/nm-dhcp-systemd.c b/src/core/dhcp/nm-dhcp-systemd.c index 5ede0df9..e1761523 100644 --- a/src/core/dhcp/nm-dhcp-systemd.c +++ b/src/core/dhcp/nm-dhcp-systemd.c @@ -157,7 +157,7 @@ lease_to_ip6_config(NMDhcpSystemd *self, sd_dhcp6_lease *lease, gint32 ts, GErro for (i = 0; i < num; i++) { nm_inet6_ntop(&dns[i], addr_str); g_string_append(nm_gstring_add_space_delimiter(str), addr_str); - nm_l3_config_data_add_nameserver_detail(l3cd, AF_INET6, &dns[i], NULL); + nm_l3_config_data_add_nameserver_addr(l3cd, AF_INET6, &dns[i]); } nm_dhcp_option_add_option(options, TRUE, diff --git a/src/core/dhcp/nm-dhcp-utils.c b/src/core/dhcp/nm-dhcp-utils.c index ca1c0482..15293fa3 100644 --- a/src/core/dhcp/nm-dhcp-utils.c +++ b/src/core/dhcp/nm-dhcp-utils.c @@ -92,7 +92,7 @@ ip4_process_dhcpcd_rfc3442_routes(const char *iface, nm_l3_config_data_add_route_4( l3cd, - &((const NMPlatformIP4Route){ + &((const NMPlatformIP4Route) { .rt_source = NM_IP_CONFIG_SOURCE_DHCP, .network = nm_ip4_addr_clear_host_address(rt_addr, rt_cidr), .plen = rt_cidr, @@ -147,7 +147,7 @@ process_dhclient_rfc3442_route(const char *const **p_octets, NMPlatformIP4Route if (inet_pton(AF_INET, next_hop, &tmp_addr) <= 0) return FALSE; - *route = (NMPlatformIP4Route){ + *route = (NMPlatformIP4Route) { .network = v_network, .plen = v_plen, .gateway = tmp_addr, @@ -316,7 +316,7 @@ process_classful_routes(const char *iface, // FIXME: ensure the IP address and route are sane - route = (NMPlatformIP4Route){ + route = (NMPlatformIP4Route) { .network = rt_addr, }; @@ -409,7 +409,7 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx, now = nm_utils_get_monotonic_timestamp_sec(); - address = (NMPlatformIP4Address){ + address = (NMPlatformIP4Address) { .timestamp = now, }; @@ -499,7 +499,7 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx, for (s = dns; dns && *s; s++) { if (inet_pton(AF_INET, *s, &tmp_addr) > 0) { if (tmp_addr) { - nm_l3_config_data_add_nameserver_detail(l3cd, AF_INET, &tmp_addr, NULL); + nm_l3_config_data_add_nameserver_addr(l3cd, AF_INET, &tmp_addr); _LOG2I(LOGD_DHCP4, iface, " nameserver '%s'", *s); } } else @@ -655,7 +655,7 @@ nm_dhcp_utils_ip6_config_from_options(NMDedupMultiIndex *multi_idx, now = nm_utils_get_monotonic_timestamp_sec(); - address = (NMPlatformIP6Address){ + address = (NMPlatformIP6Address) { .plen = 128, .timestamp = now, }; @@ -704,7 +704,7 @@ nm_dhcp_utils_ip6_config_from_options(NMDedupMultiIndex *multi_idx, for (s = dns; dns && *s; s++) { if (inet_pton(AF_INET6, *s, &tmp_addr) > 0) { if (!IN6_IS_ADDR_UNSPECIFIED(&tmp_addr)) { - nm_l3_config_data_add_nameserver_detail(l3cd, AF_INET6, &tmp_addr, NULL); + nm_l3_config_data_add_nameserver_addr(l3cd, AF_INET6, &tmp_addr); _LOG2I(LOGD_DHCP6, iface, " nameserver '%s'", *s); } } else @@ -935,6 +935,27 @@ nm_dhcp_lease_data_parse_u16(const guint8 *data, } gboolean +nm_dhcp_lease_data_parse_u32(const guint8 *data, + gsize n_data, + uint32_t *out_val, + const char *iface, + int addr_family, + guint option) +{ + if (n_data != 4) { + nm_dhcp_lease_log_invalid_option(iface, + addr_family, + option, + "invalid option length %lu", + (unsigned long) n_data); + return FALSE; + } + + *out_val = unaligned_read_be32(data); + return TRUE; +} + +gboolean nm_dhcp_lease_data_parse_mtu(const guint8 *data, gsize n_data, uint16_t *out_val, diff --git a/src/core/dhcp/nm-dhcp-utils.h b/src/core/dhcp/nm-dhcp-utils.h index 00199b02..99898524 100644 --- a/src/core/dhcp/nm-dhcp-utils.h +++ b/src/core/dhcp/nm-dhcp-utils.h @@ -74,6 +74,12 @@ gboolean nm_dhcp_lease_data_parse_u16(const guint8 *data, const char *iface, int addr_family, guint option); +gboolean nm_dhcp_lease_data_parse_u32(const guint8 *data, + gsize n_data, + uint32_t *out_val, + const char *iface, + int addr_family, + guint option); gboolean nm_dhcp_lease_data_parse_mtu(const guint8 *data, gsize n_data, guint16 *out_val, diff --git a/src/core/dhcp/tests/test-dhcp-dhclient.c b/src/core/dhcp/tests/test-dhcp-dhclient.c index 0edcc296..6a7b7185 100644 --- a/src/core/dhcp/tests/test-dhcp-dhclient.c +++ b/src/core/dhcp/tests/test-dhcp-dhclient.c @@ -1023,7 +1023,7 @@ _check_duid_impl(const guint8 *duid_bin, g_assert_cmpint(contents_len, ==, strlen(contents)); } -#define _DUID(...) ((const guint8[]){__VA_ARGS__}) +#define _DUID(...) ((const guint8[]) {__VA_ARGS__}) #define _check_duid(duid, enforce_duid, old_content, new_content) \ _check_duid_impl((duid), sizeof(duid), (enforce_duid), (old_content), (new_content)) diff --git a/src/core/dhcp/tests/test-dhcp-utils.c b/src/core/dhcp/tests/test-dhcp-utils.c index 1c6d6302..b81523e1 100644 --- a/src/core/dhcp/tests/test-dhcp-utils.c +++ b/src/core/dhcp/tests/test-dhcp-utils.c @@ -194,16 +194,16 @@ test_parse_search_list(void) guint8 *data; char **domains; - data = (guint8[]){0x05, 'l', 'o', 'c', 'a', 'l', 0x00}; + data = (guint8[]) {0x05, 'l', 'o', 'c', 'a', 'l', 0x00}; domains = nm_dhcp_lease_data_parse_search_list(data, 7, NULL, 0, 0); g_assert(domains); g_assert_cmpint(g_strv_length(domains), ==, 1); g_assert_cmpstr(domains[0], ==, "local"); g_strfreev(domains); - data = (guint8[]){0x04, 't', 'e', 's', 't', 0x07, 'e', 'x', 'a', 'm', 'p', 'l', - 'e', 0x03, 'c', 'o', 'm', 0x00, 0xc0, 0x05, 0x03, 'a', 'b', 'c', - 0xc0, 0x0d, 0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0x00}; + data = (guint8[]) {0x04, 't', 'e', 's', 't', 0x07, 'e', 'x', 'a', 'm', 'p', 'l', + 'e', 0x03, 'c', 'o', 'm', 0x00, 0xc0, 0x05, 0x03, 'a', 'b', 'c', + 0xc0, 0x0d, 0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0x00}; domains = nm_dhcp_lease_data_parse_search_list(data, 34, NULL, 0, 0); g_assert(domains); g_assert_cmpint(g_strv_length(domains), ==, 4); @@ -213,7 +213,7 @@ test_parse_search_list(void) g_assert_cmpstr(domains[3], ==, "foobar"); g_strfreev(domains); - data = (guint8[]){ + data = (guint8[]) { 0x40, 'b', 'a', @@ -222,7 +222,7 @@ test_parse_search_list(void) domains = nm_dhcp_lease_data_parse_search_list(data, 4, NULL, 0, 0); g_assert(!domains); - data = (guint8[]){ + data = (guint8[]) { 0x04, 'o', 'k', diff --git a/src/core/dns/nm-dns-dnsconfd.c b/src/core/dns/nm-dns-dnsconfd.c new file mode 100644 index 00000000..b356c2f9 --- /dev/null +++ b/src/core/dns/nm-dns-dnsconfd.c @@ -0,0 +1,802 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024 Red Hat, Inc. + */ + +#include "src/core/nm-default-daemon.h" + +#include "nm-dns-dnsconfd.h" + +#include "libnm-glib-aux/nm-dbus-aux.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-platform/nm-platform.h" +#include "nm-utils.h" +#include "nm-dbus-manager.h" +#include "NetworkManagerUtils.h" +#include "nm-l3-config-data.h" +#include "nm-manager.h" +#include "devices/nm-device.h" +#include "nm-active-connection.h" +#include "nm-l3cfg.h" + +typedef enum { + DNSCONFD_PLUGIN_IDLE = 0, + DNSCONFD_PLUGIN_WAIT_CONNECT = 1, + DNSCONFD_PLUGIN_WAIT_UPDATE_DONE = 2, + DNSCONFD_PLUGIN_WAIT_SERIAL = 3 +} DnsconfdPluginState; + +typedef struct { + GDBusConnection *dbus_connection; + GCancellable *update_cancellable; + char *name_owner; + guint name_owner_changed_id; + GCancellable *name_owner_cancellable; + GVariant *latest_update_args; + + guint awaited_configuration_serial; + guint present_configuration_serial; + guint properties_changed_id; + GCancellable *serial_cancellable; + + DnsconfdPluginState plugin_state; +} NMDnsDnsconfdPrivate; + +struct _NMDnsDnsconfd { + NMDnsPlugin parent; + NMDnsDnsconfdPrivate _priv; +}; + +struct _NMDnsDnsconfdClass { + NMDnsPluginClass parent; +}; + +G_DEFINE_TYPE(NMDnsDnsconfd, nm_dns_dnsconfd, NM_TYPE_DNS_PLUGIN) + +#define NM_DNS_DNSCONFD_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDnsDnsconfd, NM_IS_DNS_DNSCONFD, NMDnsPlugin) + +#define _NMLOG_DOMAIN LOGD_DNS +#define _NMLOG(level, ...) __NMLOG_DEFAULT(level, _NMLOG_DOMAIN, "dnsconfd", __VA_ARGS__) + +#define DNSCONFD_DBUS_SERVICE "com.redhat.dnsconfd" + +typedef enum { CONNECTION_FAIL, CONNECTION_SUCCESS, CONNECTION_WAIT } ConnectionState; + +/*****************************************************************************/ + +static void +dnsconfd_serial_changed(NMDnsDnsconfd *self, guint new_serial) +{ + NMDnsDnsconfdPrivate *priv = NM_DNS_DNSCONFD_GET_PRIVATE(self); + priv->present_configuration_serial = new_serial; + if (priv->plugin_state == DNSCONFD_PLUGIN_WAIT_SERIAL + && priv->awaited_configuration_serial == new_serial) { + priv->plugin_state = DNSCONFD_PLUGIN_IDLE; + /* Update finished, serials match */ + _LOGT("serials match, update finished"); + } + + _nm_dns_plugin_update_pending_maybe_changed(NM_DNS_PLUGIN(self)); +} + +static void +dnsconfd_properties_changed(GDBusConnection *connection, + const char *sender_name, + const char *object_path, + const char *interface_name, + const char *signal_name, + GVariant *parameters, + gpointer user_data) +{ + NMDnsDnsconfd *self = user_data; + gs_unref_variant GVariant *updated_properties = NULL; + guint new_serial; + + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sa{sv}as)"))) { + _LOGW("received properties changed signal but the type is wrong"); + return; + } + + g_variant_get(parameters, "(&s@a{sv}as)", NULL, &updated_properties, NULL); + + if (!g_variant_lookup(updated_properties, "configuration_serial", "u", &new_serial)) { + _LOGT("properties changed but they do not contain new serial"); + return; + } + _LOGT("properties changed and contain new serial %u", new_serial); + + dnsconfd_serial_changed(self, new_serial); +} + +static void +dnsconfd_serial_retrieval_done(GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + NMDnsDnsconfd *self; + NMDnsDnsconfdPrivate *priv; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *response = NULL; + gs_unref_variant GVariant *new_serial_variant = NULL; + guint new_serial; + + response = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source_object), res, &error); + if (nm_utils_error_is_cancelled(error)) + return; + + self = user_data; + priv = NM_DNS_DNSCONFD_GET_PRIVATE(self); + + nm_clear_g_cancellable(&priv->serial_cancellable); + + g_variant_get(response, "(v)", &new_serial_variant); + + g_variant_get(new_serial_variant, "u", &new_serial); + + _LOGT("serial retrieval done %u", new_serial); + + dnsconfd_serial_changed(self, new_serial); +} + +static gboolean +subscribe_serial(NMDnsDnsconfd *self) +{ + NMDnsDnsconfdPrivate *priv = NM_DNS_DNSCONFD_GET_PRIVATE(self); + + priv->properties_changed_id = + g_dbus_connection_signal_subscribe(priv->dbus_connection, + priv->name_owner, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + "/com/redhat/dnsconfd", + "com.redhat.dnsconfd.Manager", + G_DBUS_SIGNAL_FLAGS_NONE, + dnsconfd_properties_changed, + self, + NULL); + if (!priv->properties_changed_id) { + return FALSE; + } + + nm_clear_g_cancellable(&priv->serial_cancellable); + + g_dbus_connection_call( + priv->dbus_connection, + priv->name_owner, + "/com/redhat/dnsconfd", + "org.freedesktop.DBus.Properties", + "Get", + g_variant_new("(ss)", "com.redhat.dnsconfd.Manager", "configuration_serial"), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + priv->serial_cancellable, + dnsconfd_serial_retrieval_done, + self); + return TRUE; +} + +static void +dnsconfd_update_done(GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + NMDnsDnsconfd *self; + NMDnsDnsconfdPrivate *priv; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *response = NULL; + guint awaited_serial; + char *dnsconfd_message; + + response = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source_object), res, &error); + + if (nm_utils_error_is_cancelled(error)) + return; + + self = user_data; + priv = NM_DNS_DNSCONFD_GET_PRIVATE(self); + + nm_clear_g_cancellable(&priv->update_cancellable); + + if (!response) + _LOGW("dnsconfd update failed: %s", error->message); + + /* By using &s we will get pointer to char data contained + * in variant and thus no freing of dnsconfd_message is required */ + g_variant_get(response, "(u&s)", &awaited_serial, &dnsconfd_message); + + if (!awaited_serial) { + _LOGW("dnsconfd refused update: %s", dnsconfd_message); + priv->plugin_state = DNSCONFD_PLUGIN_IDLE; + _nm_dns_plugin_update_pending_maybe_changed(NM_DNS_PLUGIN(self)); + return; + } + + priv->awaited_configuration_serial = awaited_serial; + _LOGT("dnsconfd accepted update, awaited serial is %u", awaited_serial); + + if (priv->awaited_configuration_serial == priv->present_configuration_serial) { + /* Serials match, update finished */ + priv->plugin_state = DNSCONFD_PLUGIN_IDLE; + _LOGT("after update serials match"); + } else { + priv->plugin_state = DNSCONFD_PLUGIN_WAIT_SERIAL; + _LOGT("after update serials don't match, waiting"); + } + + _nm_dns_plugin_update_pending_maybe_changed(NM_DNS_PLUGIN(self)); +} + +static gboolean +is_default_interface_explicit(const CList *ip_data_lst_head) +{ + guint n_domains; + const char *const *strv_domains; + NMDnsConfigIPData *ip_data; + gboolean is_routing; + + /* If there is "~." specified in any connection's active ipvX.search setting then default + * interface is explicit */ + + c_list_for_each_entry (ip_data, ip_data_lst_head, ip_data_lst) { + strv_domains = + nm_l3_config_data_get_searches(ip_data->l3cd, ip_data->addr_family, &n_domains); + for (guint i = 0; i < n_domains; i++) { + if (nm_streq(nm_utils_parse_dns_domain(strv_domains[i], &is_routing), ".")) { + return TRUE; + } + } + } + /* AFAIK it should not be passible to pass "." through DHCP and thus we will check only + * searches */ + return FALSE; +} + +static void +gather_interface_domains(NMDnsConfigIPData *ip_data, + gboolean is_default_explicit, + const char ***routing_domains, + const char ***search_domains) +{ + guint n_domains; + const char *const *strv_domains; + gboolean is_routing; + const char *cur_domain; + GPtrArray *routing_ptr_array = g_ptr_array_sized_new(5); + GPtrArray *search_ptr_array = g_ptr_array_sized_new(5); + + /* Searches have higher priority than domains (dynamically retrieved) */ + strv_domains = nm_l3_config_data_get_searches(ip_data->l3cd, ip_data->addr_family, &n_domains); + if (!n_domains) { + strv_domains = + nm_l3_config_data_get_domains(ip_data->l3cd, ip_data->addr_family, &n_domains); + } + + for (int i = 0; i < n_domains; i++) { + cur_domain = nm_utils_parse_dns_domain(strv_domains[i], &is_routing); + g_ptr_array_add(routing_ptr_array, (char *) cur_domain); + if (!is_routing) { + g_ptr_array_add(search_ptr_array, (char *) cur_domain); + } + } + + /* If there has been specified search like "~." then we will not be adding "." and respect + * users wishes */ + if (!is_default_explicit + && nm_l3_config_data_get_best_default_route(ip_data->l3cd, ip_data->addr_family)) { + g_ptr_array_add(routing_ptr_array, "."); + } + g_ptr_array_add(routing_ptr_array, NULL); + g_ptr_array_add(search_ptr_array, NULL); + + /* When array would be empty we will simply return NULL */ + *routing_domains = + (const char **) g_ptr_array_free(routing_ptr_array, (routing_ptr_array->len == 1)); + *search_domains = + (const char **) g_ptr_array_free(search_ptr_array, (search_ptr_array->len == 1)); +} + +static void +get_networks(NMDnsConfigIPData *ip_data, char ***networks) +{ + NMDedupMultiIter ipconf_iter; + const NMPObject *obj; + char s_address[INET6_ADDRSTRLEN]; + /* +4 because INET6_ADDRSTRLEN already contains byte for end of string and we need 4 bytes + * to store max 3 characters of mask and slash (/128 for example) */ + char network_buffer[INET6_ADDRSTRLEN + 4]; + const NMPlatformIPRoute *route; + GPtrArray *ptr_array = g_ptr_array_sized_new(5); + int addr_family = ip_data->addr_family; + guint IS_IPv4 = NM_IS_IPv4(addr_family); + + nm_l3_config_data_iter_obj_for_each (&ipconf_iter, + ip_data->l3cd, + &obj, + NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4)) { + route = NMP_OBJECT_CAST_IP_ROUTE(obj); + if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route) + || route->table_coerced == NM_DNS_ROUTES_FWMARK_TABLE_PRIO) { + continue; + } + nm_inet_ntop(addr_family, route->network_ptr, s_address); + nm_sprintf_buf(network_buffer, "%s/%u", s_address, route->plen); + g_ptr_array_add(ptr_array, g_strdup(network_buffer)); + } + + g_ptr_array_add(ptr_array, NULL); + /* If array would be empty then return NULL */ + *networks = (char **) g_ptr_array_free(ptr_array, ptr_array->len == 1); +} + +static void +server_builder_append_interface_info(GVariantBuilder *argument_builder, + const char *interface, + char **networks, + const char *connection_id, + const char *connection_uuid, + const char *dbus_path) +{ + if (connection_id) { + g_variant_builder_add(argument_builder, + "{sv}", + "connection-id", + g_variant_new("s", connection_id)); + } + if (connection_uuid) { + g_variant_builder_add(argument_builder, + "{sv}", + "connection-uuid", + g_variant_new("s", connection_uuid)); + } + if (dbus_path) { + g_variant_builder_add(argument_builder, + "{sv}", + "connection-object", + g_variant_new("s", dbus_path)); + } + if (interface) { + g_variant_builder_add(argument_builder, "{sv}", "interface", g_variant_new("s", interface)); + } + if (networks) { + g_variant_builder_add(argument_builder, + "{sv}", + "networks", + g_variant_new_strv((const char *const *) networks, -1)); + } + g_variant_builder_close(argument_builder); +} + +static gboolean +server_builder_append_base(GVariantBuilder *argument_builder, + int address_family, + const char *address_string, + const char *const *routing_domains, + const char *const *search_domains, + const char *ca) +{ + NMDnsServer dns_server; + gsize addr_size; + + if (!nm_dns_uri_parse(address_family, address_string, &dns_server)) + return FALSE; + addr_size = nm_utils_addr_family_to_size(dns_server.addr_family); + + g_variant_builder_open(argument_builder, G_VARIANT_TYPE("a{sv}")); + + /* No freeing needed in this section as builder takes ownership of all data */ + + g_variant_builder_add(argument_builder, + "{sv}", + "address", + nm_g_variant_new_ay((gconstpointer) &dns_server.addr, addr_size)); + if (dns_server.scheme == NM_DNS_URI_SCHEME_TLS) + g_variant_builder_add(argument_builder, "{sv}", "protocol", g_variant_new("s", "dns+tls")); + if (dns_server.servername) + g_variant_builder_add(argument_builder, + "{sv}", + "name", + g_variant_new("s", dns_server.servername)); + if (routing_domains) { + g_variant_builder_add(argument_builder, + "{sv}", + "routing_domains", + g_variant_new_strv(routing_domains, -1)); + } + if (search_domains) { + g_variant_builder_add(argument_builder, + "{sv}", + "search_domains", + g_variant_new_strv(search_domains, -1)); + } + if (ca) { + g_variant_builder_add(argument_builder, "{sv}", "ca", g_variant_new("s", ca)); + } + return TRUE; +} + +static void +parse_global_config(const NMGlobalDnsConfig *global_config, + GVariantBuilder *argument_builder, + guint *resolve_mode, + const char **ca) +{ + NMGlobalDnsDomain *domain; + const char *const *servers; + const char *name; + const char *routing_domains[2] = {0}; + const char *const *searches = nm_global_dns_config_get_searches(global_config); + guint num_domains = nm_global_dns_config_get_num_domains(global_config); + /* CA can be specified only in global config, but if it is, then we must set it for + * all servers the same, because we do not support multiple certification authorities + * (backend limitation) */ + *ca = nm_global_dns_config_get_certification_authority(global_config); + *resolve_mode = nm_global_dns_config_get_resolve_mode(global_config); + + for (guint i = 0; i < num_domains; i++) { + domain = nm_global_dns_config_get_domain(global_config, i); + servers = nm_global_dns_domain_get_servers(domain); + if (!servers) { + continue; + } + name = nm_global_dns_domain_get_name(domain); + routing_domains[0] = nm_streq(name, "*") ? "." : name; + + for (gsize j = 0; servers[j]; j++) { + if (server_builder_append_base(argument_builder, + AF_UNSPEC, + servers[j], + routing_domains, + searches, + *ca)) { + g_variant_builder_close(argument_builder); + } + } + } +} + +static void +send_dnsconfd_update(NMDnsDnsconfd *self) +{ + NMDnsDnsconfdPrivate *priv = NM_DNS_DNSCONFD_GET_PRIVATE(self); + + nm_clear_g_cancellable(&priv->update_cancellable); + priv->update_cancellable = g_cancellable_new(); + + g_dbus_connection_call(priv->dbus_connection, + priv->name_owner, + "/com/redhat/dnsconfd", + "com.redhat.dnsconfd.Manager", + "Update", + priv->latest_update_args, + NULL, + G_DBUS_CALL_FLAGS_NONE, + 20000, + priv->update_cancellable, + dnsconfd_update_done, + self); +} + +static void +name_owner_changed(NMDnsDnsconfd *self, const char *name_owner) +{ + NMDnsDnsconfdPrivate *priv = NM_DNS_DNSCONFD_GET_PRIVATE(self); + + name_owner = nm_str_not_empty(name_owner); + + if (nm_streq0(priv->name_owner, name_owner)) + return; + + g_free(priv->name_owner); + priv->name_owner = g_strdup(name_owner); + + if (!name_owner) { + _LOGD("D-Bus name for dnsconfd disappeared"); + if (priv->plugin_state == DNSCONFD_PLUGIN_WAIT_UPDATE_DONE + || priv->plugin_state == DNSCONFD_PLUGIN_WAIT_SERIAL) { + /* We were waiting for either serial or confirmation of update and name + * disappeared, thus we need to retransmit */ + priv->plugin_state = DNSCONFD_PLUGIN_WAIT_CONNECT; + _nm_dns_plugin_update_pending_maybe_changed(NM_DNS_PLUGIN(self)); + } + return; + } + + _LOGT("D-Bus name for dnsconfd got owner %s", name_owner); + + if (!subscribe_serial(self)) { + /* This means that in time between new name and subscribe serial call + * we lost the name again thus wait again */ + priv->plugin_state = DNSCONFD_PLUGIN_WAIT_CONNECT; + _LOGT("subscription failed, waiting to connect"); + } else { + priv->plugin_state = DNSCONFD_PLUGIN_WAIT_UPDATE_DONE; + _LOGT("sending update and waiting for its finish"); + send_dnsconfd_update(self); + } + + _nm_dns_plugin_update_pending_maybe_changed(NM_DNS_PLUGIN(self)); +} + +static void +name_owner_changed_cb(GDBusConnection *connection, + const char *sender_name, + const char *object_path, + const char *interface_name, + const char *signal_name, + GVariant *parameters, + gpointer user_data) +{ + NMDnsDnsconfd *self = user_data; + const char *new_owner; + + if (!g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) + return; + + g_variant_get(parameters, "(&s&s&s)", NULL, NULL, &new_owner); + + name_owner_changed(self, new_owner); +} + +static void +get_name_owner_cb(const char *name_owner, GError *error, gpointer user_data) +{ + if (nm_utils_error_is_cancelled(error)) + return; + + name_owner_changed(user_data, name_owner); +} + +static ConnectionState +ensure_all_connected(NMDnsDnsconfd *self) +{ + NMDnsDnsconfdPrivate *priv = NM_DNS_DNSCONFD_GET_PRIVATE(self); + + if (!priv->dbus_connection) { + priv->dbus_connection = nm_g_object_ref(NM_MAIN_DBUS_CONNECTION_GET); + if (!priv->dbus_connection) { + return CONNECTION_FAIL; + } + } + + if (priv->name_owner) { + return CONNECTION_SUCCESS; + } + + if (!priv->name_owner_changed_id) { + priv->name_owner_changed_id = + nm_dbus_connection_signal_subscribe_name_owner_changed(priv->dbus_connection, + DNSCONFD_DBUS_SERVICE, + name_owner_changed_cb, + self, + NULL); + } + + if (!priv->name_owner_cancellable) { + nm_clear_g_cancellable(&priv->name_owner_cancellable); + priv->name_owner_cancellable = g_cancellable_new(); + + nm_dbus_connection_call_get_name_owner(priv->dbus_connection, + DNSCONFD_DBUS_SERVICE, + -1, + priv->name_owner_cancellable, + get_name_owner_cb, + self); + } + + return CONNECTION_WAIT; +} + +static void +parse_all_interface_config(GVariantBuilder *argument_builder, + const CList *ip_data_lst_head, + const char *ca) +{ + NMDnsConfigIPData *ip_data; + const char *const *dns_server_strings; + guint nameserver_count; + const char *ifname; + NMDevice *device; + NMActiveConnection *active_connection; + NMSettingsConnection *settings_connection; + NMActRequest *act_request; + const char *connection_id; + const char *connection_uuid; + const char *dbus_path; + gboolean explicit_default = is_default_interface_explicit(ip_data_lst_head); + + c_list_for_each_entry (ip_data, ip_data_lst_head, ip_data_lst) { + /* No need to free insides of routing and search domains, as they point to data + * owned elsewhere on the other hand networks are created by us and thus we need to also + * free the data */ + gs_free const char **routing_domains = NULL; + gs_free const char **search_domains = NULL; + gs_strfreev char **networks = NULL; + + dns_server_strings = nm_l3_config_data_get_nameservers(ip_data->l3cd, + ip_data->addr_family, + &nameserver_count); + if (!nameserver_count) + continue; + ifname = nm_platform_link_get_name(NM_PLATFORM_GET, ip_data->data->ifindex); + device = nm_manager_get_device_by_ifindex(NM_MANAGER_GET, ip_data->data->ifindex); + act_request = nm_device_get_act_request(device); + active_connection = NM_ACTIVE_CONNECTION(act_request); + + /* Presume that when we have server of this interface then the interface has to have + * an active connection */ + nm_assert(active_connection); + + settings_connection = nm_active_connection_get_settings_connection(active_connection); + connection_id = nm_settings_connection_get_id(settings_connection); + connection_uuid = nm_settings_connection_get_uuid(settings_connection); + dbus_path = nm_dbus_object_get_path_still_exported(NM_DBUS_OBJECT(act_request)); + + /* dbus_path also should be set, because if we are parsing this connection then we + * expect it to be active and exported on dbus */ + nm_assert(dbus_path && dbus_path[0] != 0); + + gather_interface_domains(ip_data, explicit_default, &routing_domains, &search_domains); + get_networks(ip_data, &networks); + + for (guint i = 0; i < nameserver_count; i++) { + if (server_builder_append_base(argument_builder, + ip_data->addr_family, + dns_server_strings[i], + routing_domains, + search_domains, + ca)) { + server_builder_append_interface_info(argument_builder, + ifname, + networks, + connection_id, + connection_uuid, + dbus_path); + } + } + } +} + +static gboolean +update(NMDnsPlugin *plugin, + const NMGlobalDnsConfig *global_config, + const CList *ip_data_lst_head, + const char *hostdomain, + GError **error) +{ + NMDnsDnsconfd *self = NM_DNS_DNSCONFD(plugin); + NMDnsDnsconfdPrivate *priv = NM_DNS_DNSCONFD_GET_PRIVATE(self); + GVariantBuilder argument_builder; + GVariant *args; + + ConnectionState all_connected; + const char *ca = NULL; + guint resolve_mode = 0; + gs_free char *debug_string = NULL; + + g_variant_builder_init(&argument_builder, G_VARIANT_TYPE("(aa{sv}u)")); + g_variant_builder_open(&argument_builder, G_VARIANT_TYPE("aa{sv}")); + + if (global_config) { + _LOGT("parsing global configuration"); + parse_global_config(global_config, &argument_builder, &resolve_mode, &ca); + } + _LOGT("parsing configuration of interfaces"); + parse_all_interface_config(&argument_builder, ip_data_lst_head, ca); + + g_variant_builder_close(&argument_builder); + g_variant_builder_add(&argument_builder, "u", resolve_mode); + + args = g_variant_builder_end(&argument_builder); + + /* Knowing how the update looks will be immensely helpful during debugging */ + _LOGT("arguments variant is composed like: %s", (debug_string = g_variant_print(args, TRUE))); + + nm_clear_pointer(&priv->latest_update_args, g_variant_unref); + priv->latest_update_args = g_variant_ref_sink(args); + + all_connected = ensure_all_connected(self); + + /* We need to consider only whether we are connected, because newer update call + * overrides the old one */ + if (all_connected != CONNECTION_SUCCESS) { + priv->plugin_state = DNSCONFD_PLUGIN_WAIT_CONNECT; + _LOGT("not connected, waiting to connect"); + } else { + priv->plugin_state = DNSCONFD_PLUGIN_WAIT_UPDATE_DONE; + _LOGT("connected, waiting for update to finish"); + } + + if (all_connected == CONNECTION_FAIL) { + nm_utils_error_set(error, + NM_UTILS_ERROR_UNKNOWN, + "no D-Bus connection available to talk to dnsconfd"); + /* Not connected to dbus, can do nothing here */ + return FALSE; + } else if (all_connected == CONNECTION_WAIT) { + /* We do not have name owner yet, and have to wait */ + return TRUE; + } + + send_dnsconfd_update(self); + + _nm_dns_plugin_update_pending_maybe_changed(NM_DNS_PLUGIN(self)); + + return TRUE; +} + +static void +stop(NMDnsPlugin *plugin) +{ + NMDnsDnsconfd *self = NM_DNS_DNSCONFD(plugin); + NMDnsDnsconfdPrivate *priv = NM_DNS_DNSCONFD_GET_PRIVATE(self); + + nm_clear_g_cancellable(&priv->update_cancellable); + nm_clear_g_cancellable(&priv->name_owner_cancellable); + nm_clear_g_cancellable(&priv->serial_cancellable); + nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->name_owner_changed_id); + nm_clear_g_dbus_connection_signal(priv->dbus_connection, &priv->properties_changed_id); +} + +static gboolean +_update_pending_detect(NMDnsDnsconfd *self) +{ + NMDnsDnsconfdPrivate *priv = NM_DNS_DNSCONFD_GET_PRIVATE(self); + + if (priv->plugin_state == DNSCONFD_PLUGIN_IDLE) { + /* We are waiting for nothing */ + return FALSE; + } + + /* Update in progress */ + return TRUE; +} + +static gboolean +get_update_pending(NMDnsPlugin *plugin) +{ + NMDnsDnsconfd *self = NM_DNS_DNSCONFD(plugin); + return _update_pending_detect(self); +} + +static void +nm_dns_dnsconfd_init(NMDnsDnsconfd *self) +{} + +NMDnsPlugin * +nm_dns_dnsconfd_new(void) +{ + return g_object_new(NM_TYPE_DNS_DNSCONFD, NULL); +} + +static void +dispose(GObject *object) +{ + NMDnsDnsconfdPrivate *priv = NM_DNS_DNSCONFD_GET_PRIVATE(NM_DNS_DNSCONFD(object)); + + _LOGT("disposing of Dnsconfd plugin"); + + stop(NM_DNS_PLUGIN(object)); + if (priv->name_owner) { + nm_clear_g_free(&priv->name_owner); + } + if (priv->latest_update_args) { + nm_clear_pointer(&priv->latest_update_args, g_variant_unref); + } + + G_OBJECT_CLASS(nm_dns_dnsconfd_parent_class)->dispose(object); + + g_clear_object(&priv->dbus_connection); +} + +static void +nm_dns_dnsconfd_class_init(NMDnsDnsconfdClass *dns_class) +{ + NMDnsPluginClass *plugin_class = NM_DNS_PLUGIN_CLASS(dns_class); + GObjectClass *object_class = G_OBJECT_CLASS(dns_class); + + object_class->dispose = dispose; + + plugin_class->plugin_name = "dnsconfd"; + plugin_class->is_caching = TRUE; + plugin_class->stop = stop; + plugin_class->update = update; + plugin_class->get_update_pending = get_update_pending; +} diff --git a/src/core/dns/nm-dns-dnsconfd.h b/src/core/dns/nm-dns-dnsconfd.h new file mode 100644 index 00000000..1f71b507 --- /dev/null +++ b/src/core/dns/nm-dns-dnsconfd.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_DNS_DNSCONFD_H__ +#define __NETWORKMANAGER_DNS_DNSCONFD_H__ + +#include "nm-dns-plugin.h" +#include "nm-dns-manager.h" + +#define NM_TYPE_DNS_DNSCONFD (nm_dns_dnsconfd_get_type()) +#define NM_DNS_DNSCONFD(obj) \ + (_NM_G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DNS_DNSCONFD, NMDnsDnsconfd)) +#define NM_DNS_DNSCONFD_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DNS_DNSCONFD, NMDnsDnsconfdClass)) +#define NM_IS_DNS_DNSCONFD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DNS_DNSCONFD)) +#define NM_IS_DNS_DNSCONFD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DNS_DNSCONFD)) +#define NM_DNS_DNSCONFD_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DNS_DNSCONFD, NMDnsDnsconfdClass)) + +typedef struct _NMDnsDnsconfd NMDnsDnsconfd; +typedef struct _NMDnsDnsconfdClass NMDnsDnsconfdClass; + +GType nm_dns_dnsconfd_get_type(void); + +NMDnsPlugin *nm_dns_dnsconfd_new(void); + +#endif /* __NETWORKMANAGER_DNS_DNSCONFD_H__ */ diff --git a/src/core/dns/nm-dns-dnsmasq.c b/src/core/dns/nm-dns-dnsmasq.c index 53e40f59..8e3c10c9 100644 --- a/src/core/dns/nm-dns-dnsmasq.c +++ b/src/core/dns/nm-dns-dnsmasq.c @@ -263,7 +263,7 @@ handle_kill: PIDFILE); gl_pid.kill_external_data = g_slice_new(GlPidKillExternalData); - *gl_pid.kill_external_data = (GlPidKillExternalData){ + *gl_pid.kill_external_data = (GlPidKillExternalData) { .shutdown_wait_handle = nm_shutdown_wait_obj_register_handle_full( g_strdup_printf("kill-external-dnsmasq-process-%" G_PID_FORMAT, pid), TRUE), @@ -623,7 +623,7 @@ _gl_pid_spawn(const char *dm_binary, nm_assert(notify); nm_assert(G_IS_CANCELLABLE(cancellable)); gl_pid.spawn_data = g_slice_new(GlPidSpawnAsyncData); - *gl_pid.spawn_data = (GlPidSpawnAsyncData){ + *gl_pid.spawn_data = (GlPidSpawnAsyncData) { .dm_binary = dm_binary, .notify = notify, .notify_user_data = notify_user_data, @@ -853,13 +853,16 @@ add_global_config(NMDnsDnsmasq *self, const char *const *servers = nm_global_dns_domain_get_servers(domain); const char *name = nm_global_dns_domain_get_name(domain); - g_return_if_fail(name); + nm_assert(name); for (j = 0; servers && servers[j]; j++) { - if (!strcmp(name, "*")) - add_dnsmasq_nameserver(self, dnsmasq_servers, servers[j], NULL); - else - add_dnsmasq_nameserver(self, dnsmasq_servers, servers[j], name); + char str[NM_INET_ADDRSTRLEN]; + + /* TODO: support IPv6 link-local addresses with scope id */ + if (!nm_dns_uri_parse_plain(AF_UNSPEC, servers[j], str, NULL)) + continue; + + add_dnsmasq_nameserver(self, dnsmasq_servers, str, nm_streq(name, "*") ? NULL : name); } } } @@ -881,7 +884,7 @@ add_ip_config(NMDnsDnsmasq *self, GVariantBuilder *servers, const NMDnsConfigIPD for (i = 0; i < num; i++) { NMIPAddr a; - if (!nm_utils_dnsname_parse_assert(ip_data->addr_family, strarr[i], NULL, &a, NULL)) + if (!nm_dns_uri_parse_plain(ip_data->addr_family, strarr[i], NULL, &a)) continue; ip_addr_to_string(ip_data->addr_family, &a, iface, ip_addr_to_string_buf); diff --git a/src/core/dns/nm-dns-manager.c b/src/core/dns/nm-dns-manager.c index 8f87fec1..d47590dc 100644 --- a/src/core/dns/nm-dns-manager.c +++ b/src/core/dns/nm-dns-manager.c @@ -32,6 +32,7 @@ #include "nm-config.h" #include "nm-dbus-object.h" #include "nm-dns-dnsmasq.h" +#include "nm-dns-dnsconfd.h" #include "nm-dns-plugin.h" #include "nm-dns-systemd-resolved.h" #include "nm-ip-config.h" @@ -401,7 +402,7 @@ _dns_config_ip_data_new(NMDnsConfigData *data, nm_assert(ip_config_type != NM_DNS_IP_CONFIG_TYPE_REMOVED); ip_data = g_slice_new(NMDnsConfigIPData); - *ip_data = (NMDnsConfigIPData){ + *ip_data = (NMDnsConfigIPData) { .data = data, .source_tag = source_tag, .l3cd = nm_l3_config_data_ref_and_seal(l3cd), @@ -600,7 +601,7 @@ merge_one_l3cd(NMResolvConfData *rc, int addr_family, int ifindex, const NML3Con for (i = 0; i < num_nameservers; i++) { NMIPAddr a; - if (!nm_utils_dnsname_parse_assert(addr_family, strarr[i], NULL, &a, NULL)) + if (!nm_dns_uri_parse_plain(addr_family, strarr[i], NULL, &a)) continue; if (addr_family == AF_INET) @@ -1291,8 +1292,15 @@ merge_global_dns_config(NMResolvConfData *rc, NMGlobalDnsConfig *global_conf) if (!servers) return TRUE; - for (i = 0; servers[i]; i++) - add_string_item(rc->nameservers, servers[i], TRUE); + for (i = 0; servers[i]; i++) { + char addrstr[NM_INET_ADDRSTRLEN]; + + /* TODO: support IPv6 link-local addresses with scope id */ + if (!nm_dns_uri_parse_plain(AF_UNSPEC, servers[i], addrstr, NULL)) + continue; + + add_string_item(rc->nameservers, addrstr, TRUE); + } return TRUE; } @@ -1300,7 +1308,6 @@ merge_global_dns_config(NMResolvConfData *rc, NMGlobalDnsConfig *global_conf) static const char * get_nameserver_list(int addr_family, const NML3ConfigData *l3cd, NMStrBuf *tmp_strbuf) { - char buf[NM_INET_ADDRSTRLEN]; guint num; guint i; const char *const *strarr; @@ -1309,15 +1316,9 @@ get_nameserver_list(int addr_family, const NML3ConfigData *l3cd, NMStrBuf *tmp_s strarr = nm_l3_config_data_get_nameservers(l3cd, addr_family, &num); for (i = 0; i < num; i++) { - NMIPAddr a; - - if (!nm_utils_dnsname_parse_assert(addr_family, strarr[i], NULL, &a, NULL)) - continue; - - nm_inet_ntop(addr_family, &a, buf); if (i > 0) nm_str_buf_append_c(tmp_strbuf, ' '); - nm_str_buf_append(tmp_strbuf, buf); + nm_str_buf_append(tmp_strbuf, strarr[i]); } nm_str_buf_maybe_expand(tmp_strbuf, 1, FALSE); @@ -2108,7 +2109,7 @@ nm_dns_manager_set_ip_config(NMDnsManager *self, if (!data) { data = g_slice_new(NMDnsConfigData); - *data = (NMDnsConfigData){ + *data = (NMDnsConfigData) { .ifindex = ifindex, .self = self, .data_lst_head = C_LIST_INIT(data->data_lst_head), @@ -2525,6 +2526,12 @@ again: priv->plugin = nm_dns_dnsmasq_new(); plugin_changed = TRUE; } + } else if (nm_streq0(mode, "dnsconfd")) { + if (force_reload_plugin || !NM_IS_DNS_DNSCONFD(priv->plugin)) { + _clear_plugin(self); + priv->plugin = nm_dns_dnsconfd_new(); + plugin_changed = TRUE; + } } else { if (!NM_IN_STRSET(mode, "none", "default")) { if (mode) { @@ -2541,7 +2548,7 @@ again: if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO) { rc_manager_was_auto = TRUE; - if (nm_streq(mode, "systemd-resolved")) + if (nm_streq(mode, "systemd-resolved") || nm_streq(mode, "dnsconfd")) rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED; else if (HAS_RESOLVCONF && g_file_test(RESOLVCONF_PATH, G_FILE_TEST_IS_EXECUTABLE)) { /* We detect /sbin/resolvconf only at this stage. That means, if you install @@ -2730,7 +2737,6 @@ _get_config_variant(NMDnsManager *self) guint num_domains; guint num_searches; guint i; - char buf[NM_INET_ADDRSTRLEN]; const char *ifname; const char *const *strarr; @@ -2742,12 +2748,7 @@ _get_config_variant(NMDnsManager *self) g_variant_builder_init(&strv_builder, G_VARIANT_TYPE("as")); for (i = 0; i < num; i++) { - NMIPAddr a; - - if (!nm_utils_dnsname_parse_assert(ip_data->addr_family, strarr[i], NULL, &a, NULL)) - continue; - - g_variant_builder_add(&strv_builder, "s", nm_inet_ntop(ip_data->addr_family, &a, buf)); + g_variant_builder_add(&strv_builder, "s", strarr[i]); } g_variant_builder_add(&entry_builder, "{sv}", diff --git a/src/core/dns/nm-dns-systemd-resolved.c b/src/core/dns/nm-dns-systemd-resolved.c index 24c7c774..0701a1dc 100644 --- a/src/core/dns/nm-dns-systemd-resolved.c +++ b/src/core/dns/nm-dns-systemd-resolved.c @@ -248,7 +248,7 @@ _request_item_append(NMDnsSystemdResolved *self, RequestItem *request_item; request_item = g_slice_new(RequestItem); - *request_item = (RequestItem){ + *request_item = (RequestItem) { .ref_count = 1, .operation = operation, .argument = g_variant_ref_sink(argument), @@ -396,13 +396,24 @@ update_add_ip_config(NMDnsSystemdResolved *self, strarr = nm_l3_config_data_get_nameservers(ip_data->l3cd, ip_data->addr_family, &n); for (i = 0; i < n; i++) { - const char *server_name; - NMIPAddr a; + NMDnsServer dns_server; - if (!nm_utils_dnsname_parse_assert(ip_data->addr_family, strarr[i], NULL, &a, &server_name)) + if (!nm_dns_uri_parse(ip_data->addr_family, strarr[i], &dns_server)) continue; - if (server_name) { + if (!NM_IN_SET(dns_server.scheme, + NM_DNS_URI_SCHEME_TLS, + NM_DNS_URI_SCHEME_NONE, + NM_DNS_URI_SCHEME_UDP)) { + /* In systemd-resolved, the use of DNS-over-TLS can't be controlled + * for each name server; it is controlled via a per-link knob. + * Therefore, we pass all the addresses we know about and then let + * systemd-resolved decide whether to use DoT, based on the + * "connection.dns-over-tls" property. */ + continue; + } + + if (dns_server.servername) { NM_SET_OUT(out_require_dns_ex, TRUE); if (priv->has_set_link_dns_ex == FALSE) { /* The caller won't care about this result anymore. We can skip setting it. */ @@ -413,15 +424,19 @@ update_add_ip_config(NMDnsSystemdResolved *self, if (dns_ex) { g_variant_builder_open(dns_ex, G_VARIANT_TYPE("(iayqs)")); g_variant_builder_add(dns_ex, "i", ip_data->addr_family); - g_variant_builder_add_value(dns_ex, nm_g_variant_new_ay((gconstpointer) &a, addr_size)); + g_variant_builder_add_value( + dns_ex, + nm_g_variant_new_ay((gconstpointer) &dns_server.addr, addr_size)); g_variant_builder_add(dns_ex, "q", 0); - g_variant_builder_add(dns_ex, "s", server_name ?: ""); + g_variant_builder_add(dns_ex, "s", dns_server.servername ?: ""); g_variant_builder_close(dns_ex); } if (dns) { g_variant_builder_open(dns, G_VARIANT_TYPE("(iay)")); g_variant_builder_add(dns, "i", ip_data->addr_family); - g_variant_builder_add_value(dns, nm_g_variant_new_ay((gconstpointer) &a, addr_size)); + g_variant_builder_add_value( + dns, + nm_g_variant_new_ay((gconstpointer) &dns_server.addr, addr_size)); g_variant_builder_close(dns); } has_config = TRUE; @@ -803,7 +818,7 @@ update(NMDnsPlugin *plugin, ic = g_hash_table_lookup(interfaces, GINT_TO_POINTER(ifindex)); if (!ic) { ic = g_slice_new(InterfaceConfig); - *ic = (InterfaceConfig){ + *ic = (InterfaceConfig) { .ifindex = ifindex, .ip_data_list = g_ptr_array_sized_new(4), }; @@ -855,7 +870,7 @@ update(NMDnsPlugin *plugin, InterfaceConfig ic; _LOGT("clear previously configured ifindex %d", ifindex); - ic = (InterfaceConfig){ + ic = (InterfaceConfig) { .ifindex = ifindex, .ip_data_list = NULL, }; @@ -1053,7 +1068,7 @@ _resolve_handle_call_cb(GObject *source, GAsyncResult *result, gpointer user_dat NMDnsSystemdResolvedAddressResult *n; n = nm_g_array_append_new(v_names, NMDnsSystemdResolvedAddressResult); - *n = (NMDnsSystemdResolvedAddressResult){ + *n = (NMDnsSystemdResolvedAddressResult) { .name = g_steal_pointer(&v_name), .ifindex = v_ifindex, }; @@ -1167,7 +1182,7 @@ nm_dns_systemd_resolved_resolve_address(NMDnsSystemdResolved nm_assert(callback); handle = g_slice_new(NMDnsSystemdResolvedResolveHandle); - *handle = (NMDnsSystemdResolvedResolveHandle){ + *handle = (NMDnsSystemdResolvedResolveHandle) { .self = self, .timeout_msec = timeout_msec, .callback_user_data = user_data, diff --git a/src/core/dnsmasq/nm-dnsmasq-manager.c b/src/core/dnsmasq/nm-dnsmasq-manager.c index d245d5d3..030a8e28 100644 --- a/src/core/dnsmasq/nm-dnsmasq-manager.c +++ b/src/core/dnsmasq/nm-dnsmasq-manager.c @@ -92,6 +92,8 @@ static GPtrArray * create_dm_cmd_line(const char *iface, const NML3ConfigData *l3cd, const char *pidfile, + const char *shared_dhcp_range, + int shared_dhcp_lease_time, gboolean announce_android_metered, GError **error) { @@ -100,7 +102,6 @@ create_dm_cmd_line(const char *iface, char first[INET_ADDRSTRLEN]; char last[INET_ADDRSTRLEN]; char listen_address_s[INET_ADDRSTRLEN]; - char sbuf_addr[INET_ADDRSTRLEN]; gs_free char *error_desc = NULL; const char *dm_binary; const NMPlatformIP4Address *listen_address; @@ -108,6 +109,10 @@ create_dm_cmd_line(const char *iface, guint n; guint i; + nm_assert((shared_dhcp_lease_time == 0) || (shared_dhcp_lease_time == G_MAXINT32) + || ((NM_MIN_FINITE_LEASE_TIME <= shared_dhcp_lease_time) + && (shared_dhcp_lease_time <= NM_MAX_FINITE_LEASE_TIME))); + listen_address = NMP_OBJECT_CAST_IP4_ADDRESS( nm_l3_config_data_get_first_obj(l3cd, NMP_OBJECT_TYPE_IP4_ADDRESS, NULL)); @@ -150,14 +155,32 @@ create_dm_cmd_line(const char *iface, nm_strv_ptrarray_add_string_concat(cmd, "--listen-address=", listen_address_s); - if (!nm_dnsmasq_utils_get_range(listen_address, first, last, &error_desc)) { + shared_dhcp_lease_time = (shared_dhcp_lease_time != 0) ? shared_dhcp_lease_time : 3600; + if (shared_dhcp_range && *shared_dhcp_range) { + if (shared_dhcp_lease_time < G_MAXINT32) { + nm_strv_ptrarray_add_string_printf(cmd, + "--dhcp-range=%s,%d", + shared_dhcp_range, + shared_dhcp_lease_time); + } else { + nm_strv_ptrarray_add_string_printf(cmd, "--dhcp-range=%s,infinite", shared_dhcp_range); + } + } else if (nm_dnsmasq_utils_get_range(listen_address, first, last, &error_desc)) { + if (shared_dhcp_lease_time < G_MAXINT32) { + nm_strv_ptrarray_add_string_printf(cmd, + "--dhcp-range=%s,%s,%d", + first, + last, + shared_dhcp_lease_time); + } else { + nm_strv_ptrarray_add_string_printf(cmd, "--dhcp-range=%s,%s,infinite", first, last); + } + } else { g_set_error_literal(error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, error_desc); _LOGW("failed to find DHCP address ranges: %s", error_desc); return NULL; } - nm_strv_ptrarray_add_string_printf(cmd, "--dhcp-range=%s,%s,60m", first, last); - if (nm_l3_config_data_get_best_default_route(l3cd, AF_INET)) { nm_strv_ptrarray_add_string_concat(cmd, "--dhcp-option=option:router,", listen_address_s); } @@ -167,13 +190,13 @@ create_dm_cmd_line(const char *iface, nm_gstring_prepare(&s); g_string_append(s, "--dhcp-option=option:dns-server"); for (i = 0; i < n; i++) { - in_addr_t a; + char addrstr[NM_INET_ADDRSTRLEN]; - if (!nm_utils_dnsname_parse_assert(AF_INET, strarr[i], NULL, &a, NULL)) + if (!nm_dns_uri_parse_plain(AF_INET, strarr[i], addrstr, NULL)) continue; g_string_append_c(s, ','); - g_string_append(s, nm_inet4_ntop(a, sbuf_addr)); + g_string_append(s, addrstr); } nm_strv_ptrarray_take_gstring(cmd, &s); } @@ -249,6 +272,8 @@ out: gboolean nm_dnsmasq_manager_start(NMDnsMasqManager *manager, const NML3ConfigData *l3cd, + const char *shared_dhcp_range, + int shared_dhcp_lease_time, gboolean announce_android_metered, GError **error) { @@ -265,7 +290,13 @@ nm_dnsmasq_manager_start(NMDnsMasqManager *manager, kill_existing_by_pidfile(priv->pidfile); - dm_cmd = create_dm_cmd_line(priv->iface, l3cd, priv->pidfile, announce_android_metered, error); + dm_cmd = create_dm_cmd_line(priv->iface, + l3cd, + priv->pidfile, + shared_dhcp_range, + shared_dhcp_lease_time, + announce_android_metered, + error); if (!dm_cmd) return FALSE; diff --git a/src/core/dnsmasq/nm-dnsmasq-manager.h b/src/core/dnsmasq/nm-dnsmasq-manager.h index 2f10a9e8..a393807d 100644 --- a/src/core/dnsmasq/nm-dnsmasq-manager.h +++ b/src/core/dnsmasq/nm-dnsmasq-manager.h @@ -35,6 +35,8 @@ NMDnsMasqManager *nm_dnsmasq_manager_new(const char *iface); gboolean nm_dnsmasq_manager_start(NMDnsMasqManager *manager, const NML3ConfigData *l3cd, + const char *shared_dhcp_range, + int shared_dhcp_lease_time, gboolean announce_android_metered, GError **error); diff --git a/src/core/meson.build b/src/core/meson.build index 4419ff62..6cf891ee 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -105,6 +105,7 @@ libNetworkManager = static_library( 'devices/nm-device-hsr.c', 'devices/nm-device-infiniband.c', 'devices/nm-device-ip-tunnel.c', + 'devices/nm-device-ipvlan.c', 'devices/nm-device-loopback.c', 'devices/nm-device-macsec.c', 'devices/nm-device-macvlan.c', @@ -119,10 +120,10 @@ libNetworkManager = static_library( 'devices/nm-lldp-listener.c', 'dhcp/nm-dhcp-dhclient.c', 'dhcp/nm-dhcp-dhclient-utils.c', - 'dhcp/nm-dhcp-dhcpcanon.c', 'dhcp/nm-dhcp-dhcpcd.c', 'dhcp/nm-dhcp-listener.c', 'dns/nm-dns-dnsmasq.c', + 'dns/nm-dns-dnsconfd.c', 'dns/nm-dns-manager.c', 'dns/nm-dns-plugin.c', 'dns/nm-dns-systemd-resolved.c', diff --git a/src/core/ndisc/nm-fake-ndisc.c b/src/core/ndisc/nm-fake-ndisc.c index f0b6dcf6..b2858848 100644 --- a/src/core/ndisc/nm-fake-ndisc.c +++ b/src/core/ndisc/nm-fake-ndisc.c @@ -161,7 +161,7 @@ nm_fake_ndisc_add_prefix(NMFakeNDisc *self, g_assert(ra); prefix = nm_g_array_append_new(ra->prefixes, FakePrefix); - *prefix = (FakePrefix){ + *prefix = (FakePrefix) { .plen = plen, .expiry_msec = expiry_msec, .expiry_preferred_msec = expiry_preferred_msec, diff --git a/src/core/ndisc/nm-lndp-ndisc.c b/src/core/ndisc/nm-lndp-ndisc.c index eea79373..33e9ebf3 100644 --- a/src/core/ndisc/nm-lndp-ndisc.c +++ b/src/core/ndisc/nm-lndp-ndisc.c @@ -181,7 +181,7 @@ receive_ra(struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) * SHOULD NOT appear on the default router list. * * We handle that by tracking a gateway that expires right now. */ - gateway = (NMNDiscGateway){ + gateway = (NMNDiscGateway) { .address = gateway_addr, .expiry_msec = _nm_ndisc_lifetime_to_expiry(now_msec, ndp_msgra_router_lifetime(msgra)), .preference = _route_preference_coerce(ndp_msgra_route_preference(msgra)), diff --git a/src/core/ndisc/nm-ndisc.c b/src/core/ndisc/nm-ndisc.c index 86b7da6e..ad2edd8d 100644 --- a/src/core/ndisc/nm-ndisc.c +++ b/src/core/ndisc/nm-ndisc.c @@ -130,7 +130,7 @@ nm_ndisc_data_to_l3cd(NMDedupMultiIndex *multi_idx, const NMNDiscAddress *ndisc_addr = &rdata->addresses[i]; NMPlatformIP6Address a; - a = (NMPlatformIP6Address){ + a = (NMPlatformIP6Address) { .ifindex = ifindex, .address = ndisc_addr->address, .plen = 64, @@ -151,7 +151,7 @@ nm_ndisc_data_to_l3cd(NMDedupMultiIndex *multi_idx, const NMNDiscRoute *ndisc_route = &rdata->routes[i]; NMPlatformIP6Route r; - r = (NMPlatformIP6Route){ + r = (NMPlatformIP6Route) { .ifindex = ifindex, .network = ndisc_route->network, .plen = ndisc_route->plen, @@ -205,10 +205,7 @@ nm_ndisc_data_to_l3cd(NMDedupMultiIndex *multi_idx, } for (i = 0; i < rdata->dns_servers_n; i++) { - nm_l3_config_data_add_nameserver_detail(l3cd, - AF_INET6, - &rdata->dns_servers[i].address, - NULL); + nm_l3_config_data_add_nameserver_addr(l3cd, AF_INET6, &rdata->dns_servers[i].address); } for (i = 0; i < rdata->dns_domains_n; i++) @@ -836,7 +833,7 @@ nm_ndisc_add_dns_domain(NMNDisc *ndisc, const NMNDiscDNSDomain *new_item, gint64 return FALSE; item = nm_g_array_append_new(rdata->dns_domains, NMNDiscDNSDomain); - *item = (NMNDiscDNSDomain){ + *item = (NMNDiscDNSDomain) { .domain = g_strdup(new_item->domain), .expiry_msec = new_item->expiry_msec, }; @@ -991,9 +988,8 @@ announce_router(NMNDisc *ndisc) /* Schedule next initial announcement retransmit. */ priv->send_ra_id = - g_timeout_add_seconds(nm_random_u64_range_full(NM_NDISC_ROUTER_ADVERT_DELAY, - NM_NDISC_ROUTER_ADVERT_INITIAL_INTERVAL, - FALSE), + g_timeout_add_seconds(nm_random_u64_range(NM_NDISC_ROUTER_ADVERT_DELAY, + NM_NDISC_ROUTER_ADVERT_INITIAL_INTERVAL), (GSourceFunc) announce_router, ndisc); } else { @@ -1027,9 +1023,10 @@ announce_router_initial(NMNDisc *ndisc) /* Schedule the initial send rather early. Clamp the delay by minimal * delay and not the initial advert internal so that we start fast. */ if (G_LIKELY(!priv->send_ra_id)) { - priv->send_ra_id = g_timeout_add_seconds(nm_random_u64_range(NM_NDISC_ROUTER_ADVERT_DELAY), - (GSourceFunc) announce_router, - ndisc); + priv->send_ra_id = + g_timeout_add_seconds(nm_random_u64_range(0, NM_NDISC_ROUTER_ADVERT_DELAY), + (GSourceFunc) announce_router, + ndisc); } } @@ -1045,7 +1042,7 @@ announce_router_solicited(NMNDisc *ndisc) nm_clear_g_source(&priv->send_ra_id); if (!priv->send_ra_id) { - priv->send_ra_id = g_timeout_add(nm_random_u64_range(NM_NDISC_ROUTER_ADVERT_DELAY_MS), + priv->send_ra_id = g_timeout_add(nm_random_u64_range(0, NM_NDISC_ROUTER_ADVERT_DELAY_MS), (GSourceFunc) announce_router, ndisc); } @@ -1090,7 +1087,7 @@ nm_ndisc_set_config(NMNDisc *ndisc, const NML3ConfigData *l3cd) if (!lifetime) continue; - a = (NMNDiscAddress){ + a = (NMNDiscAddress) { .address = addr->address, .expiry_msec = _nm_ndisc_lifetime_to_expiry(NM_NDISC_EXPIRY_BASE_TIMESTAMP, lifetime), .expiry_preferred_msec = @@ -1106,14 +1103,14 @@ nm_ndisc_set_config(NMNDisc *ndisc, const NML3ConfigData *l3cd) if (l3cd) strvarr = nm_l3_config_data_get_nameservers(l3cd, AF_INET6, &len); for (i = 0; i < len; i++) { - struct in6_addr a; + NMIPAddr a; NMNDiscDNSServer n; - if (!nm_utils_dnsname_parse_assert(AF_INET6, strvarr[i], NULL, &a, NULL)) + if (!nm_dns_uri_parse_plain(AF_INET6, strvarr[i], NULL, &a)) continue; - n = (NMNDiscDNSServer){ - .address = a, + n = (NMNDiscDNSServer) { + .address = a.addr6, .expiry_msec = _nm_ndisc_lifetime_to_expiry(NM_NDISC_EXPIRY_BASE_TIMESTAMP, NM_NDISC_ROUTER_LIFETIME), }; @@ -1128,7 +1125,7 @@ nm_ndisc_set_config(NMNDisc *ndisc, const NML3ConfigData *l3cd) for (i = 0; i < len; i++) { NMNDiscDNSDomain n; - n = (NMNDiscDNSDomain){ + n = (NMNDiscDNSDomain) { .domain = (char *) strvarr[i], .expiry_msec = _nm_ndisc_lifetime_to_expiry(NM_NDISC_EXPIRY_BASE_TIMESTAMP, NM_NDISC_ROUTER_LIFETIME), diff --git a/src/core/ndisc/nm-ndisc.h b/src/core/ndisc/nm-ndisc.h index b8f8b06e..8f1a12a2 100644 --- a/src/core/ndisc/nm-ndisc.h +++ b/src/core/ndisc/nm-ndisc.h @@ -40,7 +40,7 @@ typedef enum { const char *nm_ndisc_dhcp_level_to_string(NMNDiscDHCPLevel level); -#define NM_NDISC_INFINITY_U32 ((uint32_t) - 1) +#define NM_NDISC_INFINITY_U32 ((uint32_t) -1) /* It's important that this is G_MAXINT64, so that we can meaningfully do * MIN(e1, e2) to find the minimum expiry time (and properly handle if any diff --git a/src/core/ndisc/tests/test-ndisc-linux.c b/src/core/ndisc/tests/test-ndisc-linux.c index 66c7e157..e4184184 100644 --- a/src/core/ndisc/tests/test-ndisc-linux.c +++ b/src/core/ndisc/tests/test-ndisc-linux.c @@ -62,7 +62,7 @@ main(int argc, char **argv) l3cfg = nm_netns_l3cfg_acquire(NM_NETNS_GET, ifindex); - config = (NMNDiscConfig){ + config = (NMNDiscConfig) { .l3cfg = l3cfg, .ifname = nm_l3cfg_get_ifname(l3cfg, TRUE), .stable_type = NM_UTILS_STABLE_TYPE_UUID, diff --git a/src/core/nm-audit-manager.c b/src/core/nm-audit-manager.c index 7cf52946..70d5d88b 100644 --- a/src/core/nm-audit-manager.c +++ b/src/core/nm-audit-manager.c @@ -90,7 +90,7 @@ _audit_field_init_string(AuditField *field, gboolean need_encoding, AuditBackend backends) { - *field = (AuditField){ + *field = (AuditField) { .name = name, .need_encoding = need_encoding, .backends = backends, @@ -102,7 +102,7 @@ _audit_field_init_string(AuditField *field, static void _audit_field_init_uint64(AuditField *field, const char *name, guint64 val, AuditBackend backends) { - *field = (AuditField){ + *field = (AuditField) { .name = name, .backends = backends, .value_type = NM_VALUE_TYPE_UINT64, diff --git a/src/core/nm-auth-manager.c b/src/core/nm-auth-manager.c index 242f0055..65357a9f 100644 --- a/src/core/nm-auth-manager.c +++ b/src/core/nm-auth-manager.c @@ -327,7 +327,7 @@ nm_auth_manager_check_authorization(NMAuthManager *self : POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE; call_id = g_slice_new(NMAuthManagerCallId); - *call_id = (NMAuthManagerCallId){ + *call_id = (NMAuthManagerCallId) { .self = g_object_ref(self), .callback = callback, .user_data = user_data, diff --git a/src/core/nm-auth-utils.c b/src/core/nm-auth-utils.c index aa2547b3..389004aa 100644 --- a/src/core/nm-auth-utils.c +++ b/src/core/nm-auth-utils.c @@ -293,7 +293,7 @@ nm_auth_chain_set_data_unsafe(NMAuthChain *self, } chain_data = &self->data_arr[self->data_len++]; - *chain_data = (ChainData){ + *chain_data = (ChainData) { .tag = tag, .data = data, .destroy = data_destroy, @@ -445,7 +445,7 @@ nm_auth_chain_add_call_unsafe(NMAuthChain *self, const char *permission, gboolea } call = g_slice_new(AuthCall); - *call = (AuthCall){ + *call = (AuthCall) { .chain = self, .call_id = NULL, .result = NM_AUTH_CALL_RESULT_UNKNOWN, @@ -520,7 +520,7 @@ nm_auth_chain_new_subject(NMAuthSubject *subject, nm_assert(done_func); self = g_slice_new(NMAuthChain); - *self = (NMAuthChain){ + *self = (NMAuthChain) { .done_func = done_func, .user_data = user_data, .context = nm_g_object_ref(context), diff --git a/src/core/nm-bond-manager.c b/src/core/nm-bond-manager.c index f24c8163..2f7fe36c 100644 --- a/src/core/nm-bond-manager.c +++ b/src/core/nm-bond-manager.c @@ -994,7 +994,7 @@ nm_bond_manager_new(struct _NMPlatform *platform, nm_assert(ifindex > 0); self = g_slice_new(NMBondManager); - *self = (NMBondManager){ + *self = (NMBondManager) { .platform = g_object_ref(platform), .ifindex = ifindex, .reg_state = REGISTRATION_STATE_NONE, diff --git a/src/core/nm-config-data.c b/src/core/nm-config-data.c index 0a73695a..5a84a2c8 100644 --- a/src/core/nm-config-data.c +++ b/src/core/nm-config-data.c @@ -46,11 +46,13 @@ struct _NMGlobalDnsDomain { }; struct _NMGlobalDnsConfig { - char **searches; - char **options; - GHashTable *domains; - const char **domain_list; - gboolean internal; + char **searches; + char **options; + GHashTable *domains; + const char **domain_list; + gboolean internal; + char *cert_authority; + NMDnsResolveMode resolve_mode; }; /*****************************************************************************/ @@ -399,7 +401,7 @@ nm_config_data_get_ignore_carrier_for_port(const NMConfigData *self, if (!nm_utils_ifname_valid_kernel(controller, NULL)) goto out_default; - match_data = (NMMatchSpecDeviceData){ + match_data = (NMMatchSpecDeviceData) { .interface_name = controller, .device_type = port_type, }; @@ -955,6 +957,22 @@ nm_global_dns_config_get_options(const NMGlobalDnsConfig *dns_config) return (const char *const *) dns_config->options; } +const char * +nm_global_dns_config_get_certification_authority(const NMGlobalDnsConfig *dns_config) +{ + g_return_val_if_fail(dns_config, NULL); + + return (const char *) dns_config->cert_authority; +} + +guint +nm_global_dns_config_get_resolve_mode(const NMGlobalDnsConfig *dns_config) +{ + g_return_val_if_fail(dns_config, 0); + + return dns_config->resolve_mode; +} + guint nm_global_dns_config_get_num_domains(const NMGlobalDnsConfig *dns_config) { @@ -1155,6 +1173,9 @@ nm_global_dns_config_free(NMGlobalDnsConfig *dns_config) g_free(dns_config->domain_list); if (dns_config->domains) g_hash_table_unref(dns_config->domains); + if (dns_config->cert_authority) { + g_free(dns_config->cert_authority); + } g_free(dns_config); } } @@ -1180,6 +1201,29 @@ global_dns_config_seal_domains(NMGlobalDnsConfig *dns_config) dns_config->domain_list = nm_strdict_get_keys(dns_config->domains, TRUE, NULL); } +static const char * +nm_dns_resolve_mode_to_string(const NMDnsResolveMode mode) +{ + const char *to_string[3] = {"backup", "prefer", "exclusive"}; + + nm_assert(mode < _NM_NUM_DNS_RESOLVE_MODES); + + return to_string[mode]; +} + +static NMDnsResolveMode +nm_dns_resolve_mode_from_string(const char *string) +{ + if (nm_streq0(string, "backup")) { + return NM_DNS_RESOLVE_MODE_BACKUP; + } else if (nm_streq0(string, "prefer")) { + return NM_DNS_RESOLVE_MODE_PREFER; + } else if (nm_streq0(string, "exclusive")) { + return NM_DNS_RESOLVE_MODE_EXCLUSIVE; + } + return _NM_NUM_DNS_RESOLVE_MODES; +} + static NMGlobalDnsConfig * load_global_dns(GKeyFile *keyfile, gboolean internal) { @@ -1189,6 +1233,9 @@ load_global_dns(GKeyFile *keyfile, gboolean internal) int g, i, j, domain_prefix_len; gboolean default_found = FALSE; char **strv; + gs_free char *cert_authority = NULL; + gs_free char *resolve_mode = NULL; + NMDnsResolveMode parsed_resolve_mode; if (internal) { group = NM_CONFIG_KEYFILE_GROUP_INTERN_GLOBAL_DNS; @@ -1202,7 +1249,31 @@ load_global_dns(GKeyFile *keyfile, gboolean internal) if (!nm_config_keyfile_has_global_dns_config(keyfile, internal)) return NULL; - dns_config = g_malloc0(sizeof(NMGlobalDnsConfig)); + dns_config = g_malloc0(sizeof(NMGlobalDnsConfig)); + + cert_authority = g_key_file_get_string(keyfile, + group, + NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_CERTIFICATION_AUTHORITY, + NULL); + if (cert_authority) { + dns_config->cert_authority = g_steal_pointer(&cert_authority); + } + + resolve_mode = + g_key_file_get_string(keyfile, group, NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_RESOLVE_MODE, NULL); + + if (resolve_mode) { + parsed_resolve_mode = nm_dns_resolve_mode_from_string(resolve_mode); + if (parsed_resolve_mode == _NM_NUM_DNS_RESOLVE_MODES) { + nm_log_dbg(LOGD_CORE, + "%s global DNS configuration has invalid value '%s', assuming backup", + internal ? "internal" : "user", + NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_RESOLVE_MODE); + } else { + dns_config->resolve_mode = parsed_resolve_mode; + } + } + dns_config->domains = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, @@ -1259,10 +1330,19 @@ load_global_dns(GKeyFile *keyfile, gboolean internal) if (strv) { nm_strv_cleanup(strv, TRUE, TRUE, TRUE); for (i = 0, j = 0; strv[i]; i++) { - if (nm_inet_is_valid(AF_INET, strv[i]) || nm_inet_is_valid(AF_INET6, strv[i])) - strv[j++] = strv[i]; - else + gs_free char *to_free = NULL; + + if (nm_dns_uri_normalize(AF_UNSPEC, strv[i], &to_free)) { + if (to_free) { + g_free(strv[i]); + strv[j++] = g_steal_pointer(&to_free); + } else { + strv[j++] = strv[i]; + } + } else { + nm_log_dbg(LOGD_CORE, "invalid global name server \"%s\"", strv[i]); g_free(strv[i]); + } } if (j == 0) g_free(strv); @@ -1335,6 +1415,21 @@ nm_global_dns_config_to_dbus(const NMGlobalDnsConfig *dns_config, GValue *value) g_variant_new_strv((const char *const *) dns_config->options, -1)); } + if (dns_config->cert_authority) { + g_variant_builder_add(&conf_builder, + "{sv}", + "certification-authority", + g_variant_new("s", dns_config->cert_authority)); + } + + if (dns_config->resolve_mode) { + g_variant_builder_add( + &conf_builder, + "{sv}", + "resolve-mode", + g_variant_new("s", nm_dns_resolve_mode_to_string(dns_config->resolve_mode))); + } + g_variant_builder_init(&domains_builder, G_VARIANT_TYPE("a{sv}")); if (dns_config->domain_list) { for (i = 0; dns_config->domain_list[i]; i++) { @@ -1435,6 +1530,7 @@ nm_global_dns_config_from_dbus(const GValue *value, GError **error) GVariantIter iter; char **strv, *key; int i, j; + gs_free char *resolve_mode_buffer = NULL; if (!G_VALUE_HOLDS_VARIANT(value)) { g_set_error(error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, "invalid value type"); @@ -1490,7 +1586,23 @@ nm_global_dns_config_from_dbus(const GValue *value, GError **error) } g_variant_unref(v); } + } else if (nm_streq0(key, "resolve-mode") + && g_variant_is_of_type(val, G_VARIANT_TYPE("s"))) { + g_variant_get(val, "s", &resolve_mode_buffer); + dns_config->resolve_mode = nm_dns_resolve_mode_from_string(resolve_mode_buffer); + if (dns_config->resolve_mode == _NM_NUM_DNS_RESOLVE_MODES) { + g_set_error_literal(error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, + "Global DNS configuration contains invalid resolve-mode"); + nm_global_dns_config_free(dns_config); + return NULL; + } + } else if (nm_streq0(key, "certification-authority") + && g_variant_is_of_type(val, G_VARIANT_TYPE("s"))) { + g_variant_get(val, "s", &dns_config->cert_authority); } + g_variant_unref(val); } @@ -1879,7 +1991,7 @@ _match_section_info_init(MatchSectionInfo *connection_info, if (!value) continue; - vals[j++] = (NMUtilsNamedValue){ + vals[j++] = (NMUtilsNamedValue) { .name = g_steal_pointer(&key), .value_str = value, }; diff --git a/src/core/nm-config-data.h b/src/core/nm-config-data.h index 1ea0ccf2..d764a7c4 100644 --- a/src/core/nm-config-data.h +++ b/src/core/nm-config-data.h @@ -120,6 +120,13 @@ typedef enum { } NMConfigChangeFlags; +typedef enum { + NM_DNS_RESOLVE_MODE_BACKUP = 0, + NM_DNS_RESOLVE_MODE_PREFER = 1, + NM_DNS_RESOLVE_MODE_EXCLUSIVE = 2, + _NM_NUM_DNS_RESOLVE_MODES = 3 +} NMDnsResolveMode; + typedef struct _NMConfigDataClass NMConfigDataClass; typedef struct _NMGlobalDnsConfig NMGlobalDnsConfig; @@ -269,6 +276,9 @@ GKeyFile *nm_config_data_clone_keyfile_intern(const NMConfigData *self); const char *const *nm_global_dns_config_get_searches(const NMGlobalDnsConfig *dns_config); const char *const *nm_global_dns_config_get_options(const NMGlobalDnsConfig *dns_config); +const char *nm_global_dns_config_get_certification_authority(const NMGlobalDnsConfig *dns_config); +guint nm_global_dns_config_get_resolve_mode(const NMGlobalDnsConfig *dns_config); + guint nm_global_dns_config_get_num_domains(const NMGlobalDnsConfig *dns_config); NMGlobalDnsDomain *nm_global_dns_config_get_domain(const NMGlobalDnsConfig *dns_config, guint i); NMGlobalDnsDomain *nm_global_dns_config_lookup_domain(const NMGlobalDnsConfig *dns_config, diff --git a/src/core/nm-config.c b/src/core/nm-config.c index cc3d1135..a55d2d13 100644 --- a/src/core/nm-config.c +++ b/src/core/nm-config.c @@ -905,7 +905,9 @@ static const ConfigGroup config_groups[] = { { .group = NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS, .keys = NM_MAKE_STRV(NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_OPTIONS, - NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_SEARCHES, ), + NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_SEARCHES, + NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_CERTIFICATION_AUTHORITY, + NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_RESOLVE_MODE, ), }, { .group = NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN, @@ -1284,19 +1286,23 @@ _get_config_dir_files(const char *config_dir) static void _confs_to_description(GString *str, const GPtrArray *confs, const char *name) { - guint i; + guint i; + gboolean need_braces; if (!confs->len) return; + need_braces = confs->len > 1; + for (i = 0; i < confs->len; i++) { if (i == 0) - g_string_append_printf(str, " (%s: ", name); + g_string_append_printf(str, ", %s/%s", name, need_braces ? "{" : ""); else - g_string_append(str, ", "); + g_string_append(str, ","); g_string_append(str, confs->pdata[i]); } - g_string_append(str, ")"); + if (need_braces) + g_string_append(str, "}"); } static GKeyFile * @@ -1427,9 +1433,9 @@ read_entire_config(const NMConfigCmdLineOptions *cli, GString *str; str = g_string_new(o_config_main_file); - _confs_to_description(str, system_confs, "lib"); - _confs_to_description(str, run_confs, "run"); - _confs_to_description(str, confs, "etc"); + _confs_to_description(str, system_confs, system_config_dir); + _confs_to_description(str, run_confs, run_config_dir); + _confs_to_description(str, confs, config_dir); *out_config_description = g_string_free(str, FALSE); } NM_SET_OUT(out_config_main_file, g_steal_pointer(&o_config_main_file)); @@ -2815,12 +2821,12 @@ nm_config_reload(NMConfig *self, NMConfigChangeFlags reload_flags, gboolean emit NMConfigPrivate *priv; GError *error = NULL; GKeyFile *keyfile, *keyfile_intern; - NMConfigData *new_data = NULL; - char *config_main_file = NULL; - char *config_description = NULL; - gs_strfreev char **no_auto_default = NULL; - gboolean intern_config_needs_rewrite; - gs_unref_ptrarray GPtrArray *warnings = NULL; + NMConfigData *new_data = NULL; + char *config_main_file = NULL; + char *config_description = NULL; + gs_strfreev char **no_auto_default = NULL; + gboolean intern_config_needs_rewrite = FALSE; + gs_unref_ptrarray GPtrArray *warnings = NULL; guint i; g_return_if_fail(NM_IS_CONFIG(self)); @@ -2871,6 +2877,13 @@ nm_config_reload(NMConfig *self, NMConfigChangeFlags reload_flags, gboolean emit NULL); } + if (keyfile_intern) { + gs_free char *desc = config_description; + + config_description = + g_strdup_printf("%s, %s", config_description, priv->intern_config_file); + } + new_data = nm_config_data_new(config_main_file, config_description, (const char *const *) no_auto_default, @@ -3042,16 +3055,16 @@ nm_config_kernel_command_line_nm_debug(void) static gboolean init_sync(GInitable *initable, GCancellable *cancellable, GError **error) { - NMConfig *self = NM_CONFIG(initable); - NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE(self); - nm_auto_unref_keyfile GKeyFile *keyfile = NULL; - nm_auto_unref_keyfile GKeyFile *keyfile_intern = NULL; - gs_free char *config_main_file = NULL; - gs_free char *config_description = NULL; - gs_strfreev char **no_auto_default = NULL; - gs_unref_ptrarray GPtrArray *warnings = NULL; - gs_free char *configure_and_quit = NULL; - gboolean intern_config_needs_rewrite; + NMConfig *self = NM_CONFIG(initable); + NMConfigPrivate *priv = NM_CONFIG_GET_PRIVATE(self); + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + nm_auto_unref_keyfile GKeyFile *keyfile_intern = NULL; + gs_free char *config_main_file = NULL; + gs_free char *config_description = NULL; + gs_strfreev char **no_auto_default = NULL; + gs_unref_ptrarray GPtrArray *warnings = NULL; + gs_free char *configure_and_quit = NULL; + gboolean intern_config_needs_rewrite = FALSE; const char *s; if (priv->config_dir) { @@ -3126,6 +3139,13 @@ init_sync(GInitable *initable, GCancellable *cancellable, GError **error) NULL); } + if (keyfile_intern) { + gs_free char *desc = config_description; + + config_description = + g_strdup_printf("%s, %s", config_description, priv->intern_config_file); + } + priv->config_data_orig = nm_config_data_new(config_main_file, config_description, (const char *const *) no_auto_default, diff --git a/src/core/nm-connectivity.c b/src/core/nm-connectivity.c index 65eec36d..22e6c0d5 100644 --- a/src/core/nm-connectivity.c +++ b/src/core/nm-connectivity.c @@ -497,7 +497,7 @@ multi_socket_cb(CURL *e_handle, curl_socket_t fd, int what, void *userdata, void if (!fdp) { fdp = g_slice_new(ConCurlSockData); - *fdp = (ConCurlSockData){ + *fdp = (ConCurlSockData) { .cb_data = cb_data, }; curl_multi_assign(cb_data->concheck.curl_mhandle, fd, fdp); @@ -1291,7 +1291,7 @@ update_config(NMConnectivity *self, NMConfigData *config_data) } _con_config_unref(priv->con_config); priv->con_config = g_slice_new(ConConfig); - *priv->con_config = (ConConfig){ + *priv->con_config = (ConConfig) { .ref_count = 1, .uri = g_strdup(new_uri), .response = g_strdup(new_response), diff --git a/src/core/nm-core-utils.c b/src/core/nm-core-utils.c index 6aa38be2..895a9917 100644 --- a/src/core/nm-core-utils.c +++ b/src/core/nm-core-utils.c @@ -1434,7 +1434,7 @@ nm_match_spec_device(const GSList *specs, const NMMatchSpecDeviceData *data) if (!specs) return NM_MATCH_SPEC_NO_MATCH; - match_data = (MatchSpecDeviceData){ + match_data = (MatchSpecDeviceData) { .data = data, .device_type = nm_str_not_empty(data->device_type), .driver = nm_str_not_empty(data->driver), @@ -2834,10 +2834,7 @@ _host_id_read(guint8 **out_host_id, gsize *out_host_id_len) int base64_save = 0; gsize len; - if (nm_random_get_crypto_bytes(rnd_buf, sizeof(rnd_buf)) < 0) - nm_random_get_bytes_full(rnd_buf, sizeof(rnd_buf), &success); - else - success = TRUE; + nm_random_get_bytes(rnd_buf, sizeof(rnd_buf)); /* Our key is really binary data. But since we anyway generate a random seed * (with 32 random bytes), don't write it in binary, but instead create @@ -2858,12 +2855,9 @@ _host_id_read(guint8 **out_host_id, gsize *out_host_id_len) secret_arr = _host_id_hash_v2(new_content, len, sha256_digest); secret_len = NM_UTILS_CHECKSUM_LENGTH_SHA256; + success = TRUE; - if (!success) - nm_log_warn(LOGD_CORE, - "secret-key: failure to generate good random data for secret-key (use " - "non-persistent key)"); - else if (nm_utils_get_testing()) { + if (nm_utils_get_testing()) { /* for test code, we don't write the generated secret-key to disk. */ } else if (!nm_utils_file_set_contents(SECRET_KEY_FILE, (const char *) new_content, @@ -3011,7 +3005,7 @@ nmtst_utils_host_id_push(const guint8 *host_id, h = nm_g_array_append_new(nmtst_host_id_stack, HostIdData); - *h = (HostIdData){ + *h = (HostIdData) { .host_id = nm_memdup(host_id, host_id_len), .host_id_len = host_id_len, .timestamp_nsec = p_timestamp_nsec ? *p_timestamp_nsec : 0, @@ -3585,11 +3579,11 @@ _is_reserved_ipv6_iid(const guint8 *iid) /* 0200:5EFF:FE00:0000 - 0200:5EFF:FE00:5212 (Reserved IPv6 Interface Identifiers corresponding to the IANA Ethernet Block [RFC4291]) * 0200:5EFF:FE00:5213 (Proxy Mobile IPv6 [RFC6543]) * 0200:5EFF:FE00:5214 - 0200:5EFF:FEFF:FFFF (Reserved IPv6 Interface Identifiers corresponding to the IANA Ethernet Block [RFC4291]) */ - if (memcmp(iid, (const guint8[]){0x02, 0x00, 0x5E, 0xFF, 0xFE}, 5) == 0) + if (memcmp(iid, (const guint8[]) {0x02, 0x00, 0x5E, 0xFF, 0xFE}, 5) == 0) return TRUE; /* FDFF:FFFF:FFFF:FF80 - FDFF:FFFF:FFFF:FFFF (Reserved Subnet Anycast Addresses [RFC2526]) */ - if (memcmp(iid, (const guint8[]){0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 7) == 0) { + if (memcmp(iid, (const guint8[]) {0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 7) == 0) { if (iid[7] & 0x80) return TRUE; } @@ -3738,7 +3732,7 @@ _hw_addr_eth_complete(struct ether_addr *addr, nm_assert((ouis == NULL) ^ (ouis_len != 0)); if (ouis) { - oui = ouis[nm_random_u64_range(ouis_len)]; + oui = ouis[nm_random_u64_range(0, ouis_len)]; g_free(ouis); } else { if (!nm_utils_hwaddr_aton(current_mac_address, &oui, ETH_ALEN)) @@ -5255,7 +5249,7 @@ nm_utils_spawn_helper(const char *const *args, nm_assert(args && args[0]); info = g_new(HelperInfo, 1); - *info = (HelperInfo){ + *info = (HelperInfo) { .task = nm_g_task_new(NULL, cancellable, nm_utils_spawn_helper, callback, cb_data), }; diff --git a/src/core/nm-dbus-manager.c b/src/core/nm-dbus-manager.c index 7e6757f0..a89c7040 100644 --- a/src/core/nm-dbus-manager.c +++ b/src/core/nm-dbus-manager.c @@ -549,7 +549,7 @@ _get_caller_info_ensure(NMDBusManager *self, gsize l = strlen(sender) + 1; caller_info = g_malloc(sizeof(CallerInfo) + l); - *caller_info = (CallerInfo){ + *caller_info = (CallerInfo) { .uid_checked_at = -CALLER_INFO_MAX_AGE, .pid_checked_at = -CALLER_INFO_MAX_AGE, }; diff --git a/src/core/nm-dbus-object.h b/src/core/nm-dbus-object.h index 2a0ff0ee..f9427f24 100644 --- a/src/core/nm-dbus-object.h +++ b/src/core/nm-dbus-object.h @@ -29,7 +29,7 @@ typedef struct { #define NM_DBUS_EXPORT_PATH_STATIC(basepath) \ ({ \ - ((NMDBusExportPath){ \ + ((NMDBusExportPath) { \ .path = "" basepath "", \ }); \ }) @@ -37,7 +37,7 @@ typedef struct { #define NM_DBUS_EXPORT_PATH_NUMBERED(basepath) \ ({ \ static long long unsigned _int_counter = 0; \ - ((NMDBusExportPath){ \ + ((NMDBusExportPath) { \ .path = "" basepath "/%llu", \ .int_counter = &_int_counter, \ }); \ @@ -81,7 +81,7 @@ struct _NMDBusObject { }; #define NM_DEFINE_DBUS_INTERFACE_INFO(...) \ - ((NMDBusInterfaceInfo *) (&((const NMDBusInterfaceInfo){__VA_ARGS__}))) + ((NMDBusInterfaceInfo *) (&((const NMDBusInterfaceInfo) {__VA_ARGS__}))) typedef struct { GObjectClass parent; diff --git a/src/core/nm-dbus-utils.h b/src/core/nm-dbus-utils.h index 237b37d8..015ebb1e 100644 --- a/src/core/nm-dbus-utils.h +++ b/src/core/nm-dbus-utils.h @@ -50,10 +50,10 @@ extern const GDBusAnnotationInfo _nm_gdbus_annotation_info_deprecated; #define NM_GDBUS_ANNOTATION_INFO_DEPRECATED() \ ((GDBusAnnotationInfo *) &_nm_gdbus_annotation_info_deprecated) -#define NM_DEFINE_DBUS_ANNOTATION_INFO(a_key, a_value) \ - ((GDBusAnnotationInfo *) &((const GDBusAnnotationInfo){ \ - .key = (a_key), \ - .value = (a_value), \ +#define NM_DEFINE_DBUS_ANNOTATION_INFO(a_key, a_value) \ + ((GDBusAnnotationInfo *) &((const GDBusAnnotationInfo) { \ + .key = (a_key), \ + .value = (a_value), \ })) extern const GDBusAnnotationInfo *const _nm_gdbus_annotation_info_list_deprecated[]; @@ -67,10 +67,10 @@ extern const GDBusAnnotationInfo *const _nm_gdbus_annotation_info_list_deprecate ((GDBusAnnotationInfo **) _nm_gdbus_annotation_info_list_deprecated) #define NM_DEFINE_DBUS_ANNOTATION_INFOS(...) \ - ((GDBusAnnotationInfo **) ((const GDBusAnnotationInfo *const[]){__VA_ARGS__, NULL})) + ((GDBusAnnotationInfo **) ((const GDBusAnnotationInfo *const[]) {__VA_ARGS__, NULL})) #define NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE(m_name, m_signature, m_property_name, ...) \ - ((GDBusPropertyInfo *) &((const struct _NMDBusPropertyInfoExtendedBase){ \ + ((GDBusPropertyInfo *) &((const struct _NMDBusPropertyInfoExtendedBase) { \ ._parent = {.ref_count = -1, \ .name = m_name, \ .signature = m_signature, \ @@ -79,25 +79,25 @@ extern const GDBusAnnotationInfo *const _nm_gdbus_annotation_info_list_deprecate .property_name = m_property_name, \ })) -#define NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE(m_name, \ - m_signature, \ - m_property_name, \ - m_permission, \ - m_audit_op, \ - ...) \ - ((GDBusPropertyInfo *) &((const struct _NMDBusPropertyInfoExtendedReadWritable){ \ - ._base = \ - { \ - ._parent = {.ref_count = -1, \ - .name = m_name, \ - .signature = m_signature, \ - .flags = G_DBUS_PROPERTY_INFO_FLAGS_READABLE \ - | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE, \ - __VA_ARGS__}, \ - .property_name = m_property_name, \ - }, \ - .permission = m_permission, \ - .audit_op = m_audit_op, \ +#define NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE(m_name, \ + m_signature, \ + m_property_name, \ + m_permission, \ + m_audit_op, \ + ...) \ + ((GDBusPropertyInfo *) &((const struct _NMDBusPropertyInfoExtendedReadWritable) { \ + ._base = \ + { \ + ._parent = {.ref_count = -1, \ + .name = m_name, \ + .signature = m_signature, \ + .flags = G_DBUS_PROPERTY_INFO_FLAGS_READABLE \ + | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE, \ + __VA_ARGS__}, \ + .property_name = m_property_name, \ + }, \ + .permission = m_permission, \ + .audit_op = m_audit_op, \ })) typedef struct _NMDBusMethodInfoExtended { @@ -113,7 +113,7 @@ typedef struct _NMDBusMethodInfoExtended { } NMDBusMethodInfoExtended; #define NM_DEFINE_DBUS_METHOD_INFO_EXTENDED(parent_, ...) \ - ((GDBusMethodInfo *) (&((const NMDBusMethodInfoExtended){.parent = parent_, __VA_ARGS__}))) + ((GDBusMethodInfo *) (&((const NMDBusMethodInfoExtended) {.parent = parent_, __VA_ARGS__}))) typedef struct _NMDBusInterfaceInfoExtended { GDBusInterfaceInfo parent; diff --git a/src/core/nm-dispatcher.c b/src/core/nm-dispatcher.c index 4f442c68..16fb7e96 100644 --- a/src/core/nm-dispatcher.c +++ b/src/core/nm-dispatcher.c @@ -247,6 +247,20 @@ dump_ip_to_props(const NML3ConfigData *l3cd, int addr_family, GVariantBuilder *b } g_variant_builder_add(builder, "{sv}", "addresses", g_variant_builder_end(&int_builder)); + /* We used to send name servers as a entry with key "nameservers" and binary + * value. That no longer works because name servers can be URIs. Send the + * value as an array of strings. + * To avoid problems when the NM and NM-dispatcher version don't match (right + * after an upgrade or downgrade), still send the old key in the old format, + * and introduce a new key for the new format. */ + g_variant_builder_init(&int_builder, G_VARIANT_TYPE("as")); + strarr = nm_l3_config_data_get_nameservers(l3cd, addr_family, &n); + for (i = 0; i < n; i++) + g_variant_builder_add(&int_builder, "s", strarr[i]); + g_variant_builder_add(builder, "{sv}", "nameservers-full", g_variant_builder_end(&int_builder)); + + /* Old format for nameservers. This can be removed in the future when it's + * expected that both NM and NM-dispatcher support the new format.*/ if (IS_IPv4) g_variant_builder_init(&int_builder, G_VARIANT_TYPE("au")); else @@ -255,7 +269,7 @@ dump_ip_to_props(const NML3ConfigData *l3cd, int addr_family, GVariantBuilder *b for (i = 0; i < n; i++) { NMIPAddr a; - if (!nm_utils_dnsname_parse_assert(addr_family, strarr[i], NULL, &a, NULL)) + if (!nm_dns_uri_parse_plain(addr_family, strarr[i], NULL, &a)) continue; if (IS_IPv4) diff --git a/src/core/nm-firewall-utils.c b/src/core/nm-firewall-utils.c index a88c6f1a..b4960612 100644 --- a/src/core/nm-firewall-utils.c +++ b/src/core/nm-firewall-utils.c @@ -566,7 +566,7 @@ nm_firewall_nft_call(GBytes *stdin_buf, gs_free char *ss1 = NULL; call_data = g_slice_new(FwNftCallData); - *call_data = (FwNftCallData){ + *call_data = (FwNftCallData) { .task = nm_g_task_new(NULL, cancellable, nm_firewall_nft_call, callback, callback_user_data), .subprocess = NULL, @@ -661,7 +661,7 @@ _fw_nft_call_sync(GBytes *stdin_buf, GError **error) nm_auto_pop_and_unref_gmaincontext GMainContext *main_context = nm_g_main_context_push_thread_default(g_main_context_new()); nm_auto_unref_gmainloop GMainLoop *main_loop = g_main_loop_new(main_context, FALSE); - FwNftCallSyncData data = (FwNftCallSyncData){ + FwNftCallSyncData data = (FwNftCallSyncData) { .loop = main_loop, .error = error, }; @@ -1027,7 +1027,7 @@ nm_firewall_config_new_shared(const char *ip_iface, in_addr_t addr, guint8 plen) nm_assert(plen <= 32); self = g_slice_new(NMFirewallConfig); - *self = (NMFirewallConfig){ + *self = (NMFirewallConfig) { .ip_iface = g_strdup(ip_iface), .addr = addr, .plen = plen, diff --git a/src/core/nm-ip-config.c b/src/core/nm-ip-config.c index c4dc04da..eb0ec9aa 100644 --- a/src/core/nm-ip-config.c +++ b/src/core/nm-ip-config.c @@ -142,9 +142,9 @@ static void _l3cfg_notify_cb(NML3Cfg *l3cfg, const NML3ConfigNotifyData *notify_data, NMIPConfig *self) { switch (notify_data->notify_type) { - case NM_L3_CONFIG_NOTIFY_TYPE_L3CD_CHANGED: - if (notify_data->l3cd_changed.commited) - _handle_l3cd_changed(self, notify_data->l3cd_changed.l3cd_new); + case NM_L3_CONFIG_NOTIFY_TYPE_PRE_COMMIT: + if (notify_data->commit.l3cd_changed) + _handle_l3cd_changed(self, notify_data->commit.l3cd_new); break; case NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE: _notify_platform(self, notify_data->platform_change_on_idle.obj_type_flags); @@ -162,6 +162,7 @@ get_property_ip(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec NMIPConfig *self = NM_IP_CONFIG(object); NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE(self); const int addr_family = nm_ip_config_get_addr_family(self); + char **to_free = NULL; char sbuf_addr[NM_INET_ADDRSTRLEN]; const char *const *strv; guint len; @@ -193,7 +194,20 @@ get_property_ip(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec break; case PROP_IP_SEARCHES: strv = nm_l3_config_data_get_searches(priv->l3cd, addr_family, &len); + if (strv) { + strv = nm_utils_buf_utf8safe_escape_strv( + strv, + len, + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL + | NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII, + &to_free); + } + _value_set_variant_as(value, strv, len); + + if (to_free) { + g_strfreev(to_free); + } break; case PROP_IP_DNS_PRIORITY: v_i = nm_l3_config_data_get_dns_priority_or_default(priv->l3cd, addr_family); @@ -435,22 +449,27 @@ get_property_ip4(GObject *object, guint prop_id, GValue *value, GParamSpec *pspe else g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); for (i = 0; i < len; i++) { - in_addr_t a; - - if (!nm_utils_dnsname_parse_assert(AF_INET, strarr[i], NULL, &a, NULL)) - continue; + NMIPAddr a; - if (prop_id == PROP_IP4_NAMESERVERS) + if (prop_id == PROP_IP4_NAMESERVERS) { + if (!nm_dns_uri_parse_plain(AF_INET, strarr[i], NULL, &a)) + continue; g_variant_builder_add(&builder, "u", a); - else { + } else { GVariantBuilder nested_builder; + char addrstr[NM_INET_ADDRSTRLEN]; - nm_inet4_ntop(a, addr_str); g_variant_builder_init(&nested_builder, G_VARIANT_TYPE("a{sv}")); + if (nm_dns_uri_parse_plain(AF_INET, strarr[i], addrstr, NULL)) { + g_variant_builder_add(&nested_builder, + "{sv}", + "address", + g_variant_new_string(addrstr)); + } g_variant_builder_add(&nested_builder, "{sv}", - "address", - g_variant_new_string(addr_str)); + "uri", + g_variant_new_string(strarr[i])); g_variant_builder_add(&builder, "a{sv}", &nested_builder); } } @@ -678,12 +697,13 @@ get_property_ip6(GObject *object, guint prop_id, GValue *value, GParamSpec *pspe else { g_variant_builder_init(&builder, G_VARIANT_TYPE("aay")); for (i = 0; i < len; i++) { - struct in6_addr a; + NMIPAddr a; - if (!nm_utils_dnsname_parse_assert(AF_INET6, strarr[i], NULL, &a, NULL)) + /* TODO: expose the full URI as well */ + if (!nm_dns_uri_parse_plain(AF_INET6, strarr[i], NULL, &a)) continue; - g_variant_builder_add(&builder, "@ay", nm_g_variant_new_ay_in6addr(&a)); + g_variant_builder_add(&builder, "@ay", nm_g_variant_new_ay_in6addr(&a.addr6)); } g_value_take_variant(value, g_variant_builder_end(&builder)); } diff --git a/src/core/nm-l3-config-data.c b/src/core/nm-l3-config-data.c index 6d98e46d..70867ff7 100644 --- a/src/core/nm-l3-config-data.c +++ b/src/core/nm-l3-config-data.c @@ -163,6 +163,9 @@ struct _NML3ConfigData { bool ndisc_hop_limit_set : 1; bool ndisc_reachable_time_msec_set : 1; bool ndisc_retrans_timer_msec_set : 1; + + bool routed_dns_4 : 1; + bool routed_dns_6 : 1; }; /*****************************************************************************/ @@ -370,7 +373,8 @@ nm_l3_config_data_log(const NML3ConfigData *self, nm_assert(!NM_FLAGS_ANY(self->flags, ~(NM_L3_CONFIG_DAT_FLAGS_IGNORE_MERGE_NO_DEFAULT_ROUTES | NM_L3_CONFIG_DAT_FLAGS_HAS_DNS_PRIORITY_4 - | NM_L3_CONFIG_DAT_FLAGS_HAS_DNS_PRIORITY_6))); + | NM_L3_CONFIG_DAT_FLAGS_HAS_DNS_PRIORITY_6 + | NM_L3_CONFIG_DAT_FLAGS_HAS_IPV4_NON_LL))); _L("l3cd %s%s%s(" NM_HASH_OBFUSCATE_PTR_FMT ", ifindex=%d%s%s%s%s)", NM_PRINT_FMT_QUOTED(title, "\"", title, "\" ", ""), @@ -602,6 +606,12 @@ nm_l3_config_data_log(const NML3ConfigData *self, if (self->proxy_pac_script) _L("proxy-pac-script: %s", self->proxy_pac_script->str); + + if (self->routed_dns_4) + _L("routed-dns4: yes"); + if (self->routed_dns_6) + _L("routed-dns6: yes"); + #undef _L } @@ -677,7 +687,7 @@ nm_l3_config_data_new(NMDedupMultiIndex *multi_idx, int ifindex, NMIPConfigSourc || (source >= NM_IP_CONFIG_SOURCE_KERNEL && source <= NM_IP_CONFIG_SOURCE_USER)); self = g_slice_new(NML3ConfigData); - *self = (NML3ConfigData){ + *self = (NML3ConfigData) { .ref_count = 1, .ifindex = ifindex, .multi_idx = nm_dedup_multi_index_ref(multi_idx), @@ -1287,15 +1297,26 @@ nm_l3_config_data_add_address_full(NML3ConfigData *self, const NMPObject **out_obj_new) { const NMPObject *new; - gboolean changed; + gboolean changed; + const int IS_IPv4 = NM_IS_IPv4(addr_family); nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE)); nm_assert_addr_family(addr_family); nm_assert((!pl_new) != (!obj_new)); nm_assert(!obj_new || NMP_OBJECT_GET_ADDR_FAMILY(obj_new) == addr_family); + if (IS_IPv4 && !NM_FLAGS_HAS(self->flags, NM_L3_CONFIG_DAT_FLAGS_HAS_IPV4_NON_LL)) { + const NMPlatformIP4Address *addr; + addr = obj_new ? NMP_OBJECT_CAST_IP4_ADDRESS(obj_new) + : (const NMPlatformIP4Address *) (pl_new); + + if (!nm_platform_ip4_address_is_link_local(addr)) { + self->flags |= NM_L3_CONFIG_DAT_FLAGS_HAS_IPV4_NON_LL; + } + } + changed = _l3_config_data_add_obj(self->multi_idx, - &self->idx_addresses_x[NM_IS_IPv4(addr_family)], + &self->idx_addresses_x[IS_IPv4], self->ifindex, obj_new, (const NMPlatformObject *) pl_new, @@ -1439,8 +1460,7 @@ nm_l3_config_data_add_nameserver(NML3ConfigData *self, int addr_family, const ch if (NM_MORE_ASSERTS > 5) { gs_free char *s_free = NULL; - nm_assert( - nm_streq0(nm_utils_dnsname_normalize(addr_family, nameserver, &s_free), nameserver)); + nm_assert(nm_streq0(nm_dns_uri_normalize(addr_family, nameserver, &s_free), nameserver)); } p_arr = &self->nameservers_x[NM_IS_IPv4(addr_family)]; @@ -1453,27 +1473,16 @@ nm_l3_config_data_add_nameserver(NML3ConfigData *self, int addr_family, const ch } gboolean -nm_l3_config_data_add_nameserver_detail(NML3ConfigData *self, - int addr_family, - gconstpointer addr_bin, - const char *server_name) +nm_l3_config_data_add_nameserver_addr(NML3ConfigData *self, int addr_family, gconstpointer addr_bin) { - gs_free char *s_free = NULL; - char *s; - gsize l; + char addrstr[NM_INET_ADDRSTRLEN]; nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE)); nm_assert_addr_family(addr_family); nm_assert(addr_bin); - l = (NM_INET_ADDRSTRLEN + 2u) + (server_name ? strlen(server_name) : 0u); - - s = nm_malloc_maybe_a(300, l, &s_free); - - if (!nm_utils_dnsname_construct(addr_family, addr_bin, server_name, s, l)) - nm_assert_not_reached(); - - return nm_l3_config_data_add_nameserver(self, addr_family, s); + nm_inet_ntop(addr_family, addr_bin, addrstr); + return nm_l3_config_data_add_nameserver(self, addr_family, addrstr); } gboolean @@ -1965,6 +1974,32 @@ nm_l3_config_data_set_allow_routes_without_address(NML3ConfigData *self, } } +gboolean +nm_l3_config_data_get_routed_dns(const NML3ConfigData *self, int addr_family) +{ + const int IS_IPv4 = NM_IS_IPv4(addr_family); + + nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE)); + if (IS_IPv4) { + return self->routed_dns_4; + } else { + return self->routed_dns_6; + } +} + +void +nm_l3_config_data_set_routed_dns(NML3ConfigData *self, int addr_family, gboolean value) +{ + const int IS_IPv4 = NM_IS_IPv4(addr_family); + + nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE)); + if (IS_IPv4) { + self->routed_dns_4 = value; + } else { + self->routed_dns_6 = value; + } +} + NMProxyConfigMethod nm_l3_config_data_get_proxy_method(const NML3ConfigData *self) { @@ -2435,6 +2470,9 @@ nm_l3_config_data_cmp_full(const NML3ConfigData *a, if (a->ndisc_retrans_timer_msec_set) NM_CMP_DIRECT(a->ndisc_retrans_timer_msec_val, b->ndisc_retrans_timer_msec_val); + NM_CMP_DIRECT_UNSAFE(a->routed_dns_4, b->routed_dns_4); + NM_CMP_DIRECT_UNSAFE(a->routed_dns_6, b->routed_dns_6); + NM_CMP_FIELD(a, b, source); } @@ -2543,7 +2581,7 @@ nm_l3_config_data_get_blacklisted_ip4_routes(const NML3ConfigData *self, gboolea continue; } - rx.r4 = (NMPlatformIP4Route){ + rx.r4 = (NMPlatformIP4Route) { .ifindex = self->ifindex, .rt_source = NM_IP_CONFIG_SOURCE_KERNEL, .network = network_4, @@ -2725,7 +2763,7 @@ nm_l3_config_data_add_dependent_device_routes(NML3ConfigData *self, plen = addr_src->a6.plen; } - rx.r6 = (NMPlatformIP6Route){ + rx.r6 = (NMPlatformIP6Route) { .ifindex = self->ifindex, .rt_source = NM_IP_CONFIG_SOURCE_KERNEL, .table_coerced = nm_platform_route_table_coerce(route_table), @@ -2798,14 +2836,14 @@ _init_from_connection_ip(NML3ConfigData *self, int addr_family, NMConnection *co NMPlatformIPXRoute r; if (IS_IPv4) { - r.r4 = (NMPlatformIP4Route){ + r.r4 = (NMPlatformIP4Route) { .rt_source = NM_IP_CONFIG_SOURCE_USER, .gateway = gateway_bin.addr4, .table_any = TRUE, .metric_any = TRUE, }; } else { - r.r6 = (NMPlatformIP6Route){ + r.r6 = (NMPlatformIP6Route) { .rt_source = NM_IP_CONFIG_SOURCE_USER, .gateway = gateway_bin.addr6, .table_any = TRUE, @@ -2828,7 +2866,7 @@ _init_from_connection_ip(NML3ConfigData *self, int addr_family, NMConnection *co nm_ip_address_get_address_binary(s_addr, &addr_bin); if (IS_IPv4) { - a.a4 = (NMPlatformIP4Address){ + a.a4 = (NMPlatformIP4Address) { .address = addr_bin.addr4, .peer_address = addr_bin.addr4, .plen = nm_ip_address_get_prefix(s_addr), @@ -2842,7 +2880,7 @@ _init_from_connection_ip(NML3ConfigData *self, int addr_family, NMConnection *co nm_assert(a.a4.plen <= 32); } else { - a.a6 = (NMPlatformIP6Address){ + a.a6 = (NMPlatformIP6Address) { .address = addr_bin.addr6, .plen = nm_ip_address_get_prefix(s_addr), .lifetime = NM_PLATFORM_LIFETIME_PERMANENT, @@ -2887,7 +2925,7 @@ _init_from_connection_ip(NML3ConfigData *self, int addr_family, NMConnection *co nm_ip_addr_clear_host_address(addr_family, &network_bin, &network_bin, plen); if (IS_IPv4) { - r.r4 = (NMPlatformIP4Route){ + r.r4 = (NMPlatformIP4Route) { .network = network_bin.addr4, .plen = plen, .gateway = next_hop_bin.addr4, @@ -2897,7 +2935,7 @@ _init_from_connection_ip(NML3ConfigData *self, int addr_family, NMConnection *co }; nm_assert(r.r4.plen <= 32); } else { - r.r6 = (NMPlatformIP6Route){ + r.r6 = (NMPlatformIP6Route) { .network = network_bin.addr6, .plen = plen, .gateway = next_hop_bin.addr6, @@ -3045,14 +3083,12 @@ _init_from_platform(NML3ConfigData *self, else self->has_routes_with_type_local_6_set = FALSE; nmp_cache_iter_for_each (&iter, head_entry, &plobj) { - if (!_l3_config_data_add_obj(self->multi_idx, - &self->idx_addresses_x[IS_IPv4], - self->ifindex, - plobj, - NULL, - NM_L3_CONFIG_ADD_FLAGS_APPEND_FORCE, - NULL, - NULL)) + if (!nm_l3_config_data_add_address_full(self, + addr_family, + plobj, + NULL, + NM_L3_CONFIG_ADD_FLAGS_APPEND_FORCE, + NULL)) nm_assert_not_reached(); } head_entry = nm_l3_config_data_lookup_addresses(self, addr_family); @@ -3478,6 +3514,11 @@ nm_l3_config_data_merge(NML3ConfigData *self, if (!src->allow_routes_without_address_6) self->allow_routes_without_address_6 = FALSE; + + if (src->routed_dns_4) + self->routed_dns_4 = TRUE; + if (src->routed_dns_6) + self->routed_dns_6 = TRUE; } NML3ConfigData * diff --git a/src/core/nm-l3-config-data.h b/src/core/nm-l3-config-data.h index faf4f0bf..bcb6af67 100644 --- a/src/core/nm-l3-config-data.h +++ b/src/core/nm-l3-config-data.h @@ -28,6 +28,7 @@ typedef enum { ((is_ipv4) ? NM_L3_CONFIG_DAT_FLAGS_HAS_DNS_PRIORITY_4 \ : NM_L3_CONFIG_DAT_FLAGS_HAS_DNS_PRIORITY_6) + NM_L3_CONFIG_DAT_FLAGS_HAS_IPV4_NON_LL = (1ull << 3), } NML3ConfigDatFlags; typedef enum { @@ -499,10 +500,9 @@ nm_l3_config_data_get_nameservers(const NML3ConfigData *self, int addr_family, g gboolean nm_l3_config_data_add_nameserver(NML3ConfigData *self, int addr_family, const char *nameserver); -gboolean nm_l3_config_data_add_nameserver_detail(NML3ConfigData *self, - int addr_family, - gconstpointer addr_bin, - const char *server_name); +gboolean nm_l3_config_data_add_nameserver_addr(NML3ConfigData *self, + int addr_family, + gconstpointer addr_bin); gboolean nm_l3_config_data_clear_nameservers(NML3ConfigData *self, int addr_family); @@ -561,6 +561,9 @@ void nm_l3_config_data_set_allow_routes_without_address(NML3ConfigData *self, int addr_family, gboolean value); +gboolean nm_l3_config_data_get_routed_dns(const NML3ConfigData *self, int addr_family); +void nm_l3_config_data_set_routed_dns(NML3ConfigData *self, int addr_family, gboolean value); + NMProxyConfigMethod nm_l3_config_data_get_proxy_method(const NML3ConfigData *self); gboolean nm_l3_config_data_set_proxy_method(NML3ConfigData *self, NMProxyConfigMethod value); diff --git a/src/core/nm-l3-ipv4ll.c b/src/core/nm-l3-ipv4ll.c index 551a90fe..3c003c29 100644 --- a/src/core/nm-l3-ipv4ll.c +++ b/src/core/nm-l3-ipv4ll.c @@ -10,8 +10,6 @@ #include "n-acd/src/n-acd.h" #include "nm-core-utils.h" -#define ADDR_IPV4LL_PREFIX_LEN 16 - #define TIMED_OUT_TIME_FACTOR 5u /*****************************************************************************/ @@ -193,7 +191,7 @@ _ipv4ll_emit_signal_notify(NML3IPv4LL *self) self->notify_on_idle = FALSE; notify_data.notify_type = NM_L3_CONFIG_NOTIFY_TYPE_IPV4LL_EVENT; - notify_data.ipv4ll_event = (typeof(notify_data.ipv4ll_event)){ + notify_data.ipv4ll_event = (typeof(notify_data.ipv4ll_event)) { .ipv4ll = self, }; _nm_l3cfg_emit_signal_notify(self->l3cfg, ¬ify_data); @@ -233,7 +231,7 @@ _registration_update(NML3IPv4LL *self, if (!reg) { reg = g_slice_new(NML3IPv4LLRegistration); - *reg = (NML3IPv4LLRegistration){ + *reg = (NML3IPv4LLRegistration) { .self = self, .timeout_msec = timeout_msec, }; @@ -286,15 +284,6 @@ nm_l3_ipv4ll_register_remove(NML3IPv4LLRegistration *reg) /*****************************************************************************/ static gboolean -_ip4_address_is_link_local(const NMPlatformIP4Address *a) -{ - nm_assert(a); - - return nm_ip4_addr_is_link_local(a->address) && a->plen == ADDR_IPV4LL_PREFIX_LEN - && a->address == a->peer_address; -} - -static gboolean _acd_info_is_good(const NML3AcdAddrInfo *acd_info) { if (!acd_info) @@ -333,7 +322,7 @@ _l3cd_config_create(int ifindex, in_addr_t addr, NMDedupMultiIndex *multi_idx) NM_PLATFORM_IP4_ADDRESS_INIT(.ifindex = ifindex, .address = addr, .peer_address = addr, - .plen = ADDR_IPV4LL_PREFIX_LEN, + .plen = NM_IPV4LL_PREFIXLEN, .addr_source = NM_IP_CONFIG_SOURCE_IP4LL)); nm_l3_config_data_add_route_4(l3cd, @@ -359,7 +348,7 @@ _l3cd_config_get_addr(const NML3ConfigData *l3cd) nm_l3_config_data_iter_ip4_address_for_each (&iter, l3cd, &pladdr) { const in_addr_t addr = pladdr->address; - nm_assert(_ip4_address_is_link_local(pladdr)); + nm_assert(nm_platform_ip4_address_is_link_local(pladdr)); #if NM_MORE_ASSERTS > 10 { nm_auto_unref_l3cd const NML3ConfigData *l3cd2 = NULL; @@ -644,11 +633,11 @@ _ipv4ll_platform_ip4_address_lookup(NML3IPv4LL *self, in_addr_t addr) pladdr = nm_platform_ip4_address_get(nm_l3_ipv4ll_get_platform(self), nm_l3_ipv4ll_get_ifindex(self), addr, - ADDR_IPV4LL_PREFIX_LEN, + NM_IPV4LL_PREFIXLEN, addr); nm_assert(!pladdr || pladdr->address == addr); - nm_assert(!pladdr || _ip4_address_is_link_local(pladdr)); + nm_assert(!pladdr || nm_platform_ip4_address_is_link_local(pladdr)); return pladdr; } @@ -677,7 +666,7 @@ _ipv4ll_platform_find_addr(NML3IPv4LL *self, const NML3AcdAddrInfo **out_acd_inf nm_l3_ipv4ll_get_ifindex(self)); nm_platform_iter_obj_for_each (&iter, nm_l3_ipv4ll_get_platform(self), &lookup, &obj) { addr = NMP_OBJECT_CAST_IP4_ADDRESS(obj); - if (!_ip4_address_is_link_local(addr)) + if (!nm_platform_ip4_address_is_link_local(addr)) continue; acd_info = _ipv4ll_l3cfg_get_acd_addr_info(self, addr->address); @@ -962,7 +951,7 @@ nm_l3_ipv4ll_new(NML3Cfg *l3cfg) g_return_val_if_fail(NM_IS_L3CFG(l3cfg), NULL); self = g_slice_new(NML3IPv4LL); - *self = (NML3IPv4LL){ + *self = (NML3IPv4LL) { .l3cfg = g_object_ref(l3cfg), .ref_count = 1, .reg_lst_head = C_LIST_INIT(self->reg_lst_head), diff --git a/src/core/nm-l3-ipv6ll.c b/src/core/nm-l3-ipv6ll.c index 38aa98fc..e5f3b85e 100644 --- a/src/core/nm-l3-ipv6ll.c +++ b/src/core/nm-l3-ipv6ll.c @@ -646,7 +646,7 @@ _nm_l3_ipv6ll_new(NML3Cfg *l3cfg, NULL); self = g_slice_new(NML3IPv6LL); - *self = (NML3IPv6LL){ + *self = (NML3IPv6LL) { .l3cfg = g_object_ref(l3cfg), .notify_fcn = notify_fcn, .user_data = user_data, diff --git a/src/core/nm-l3cfg.c b/src/core/nm-l3cfg.c index a7189d3e..fb48b860 100644 --- a/src/core/nm-l3cfg.c +++ b/src/core/nm-l3cfg.c @@ -10,7 +10,9 @@ #include "nm-compat-headers/linux/if_addr.h" #include <linux/if_ether.h> #include <linux/rtnetlink.h> +#include <linux/fib_rules.h> +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-glib-aux/nm-prioq.h" #include "libnm-glib-aux/nm-time-utils.h" #include "libnm-platform/nm-platform.h" @@ -436,7 +438,6 @@ static NM_UTILS_ENUM2STR_DEFINE( NML3ConfigNotifyType, NM_UTILS_ENUM2STR(NM_L3_CONFIG_NOTIFY_TYPE_ACD_EVENT, "acd-event"), NM_UTILS_ENUM2STR(NM_L3_CONFIG_NOTIFY_TYPE_IPV4LL_EVENT, "ipv4ll-event"), - NM_UTILS_ENUM2STR(NM_L3_CONFIG_NOTIFY_TYPE_L3CD_CHANGED, "l3cd-changed"), NM_UTILS_ENUM2STR(NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE, "platform-change"), NM_UTILS_ENUM2STR(NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE, "platform-change-on-idle"), NM_UTILS_ENUM2STR(NM_L3_CONFIG_NOTIFY_TYPE_PRE_COMMIT, "pre-commit"), @@ -591,16 +592,17 @@ _l3_config_notify_data_to_string(const NML3ConfigNotifyData *notify_data, nm_strbuf_seek_end(&s, &l); switch (notify_data->notify_type) { - case NM_L3_CONFIG_NOTIFY_TYPE_L3CD_CHANGED: + case NM_L3_CONFIG_NOTIFY_TYPE_PRE_COMMIT: + case NM_L3_CONFIG_NOTIFY_TYPE_POST_COMMIT: nm_strbuf_append(&s, &l, ", l3cd-old=%s", - NM_HASH_OBFUSCATE_PTR_STR(notify_data->l3cd_changed.l3cd_old, sbufobf)); + NM_HASH_OBFUSCATE_PTR_STR(notify_data->commit.l3cd_old, sbufobf)); nm_strbuf_append(&s, &l, ", l3cd-new=%s", - NM_HASH_OBFUSCATE_PTR_STR(notify_data->l3cd_changed.l3cd_new, sbufobf)); - nm_strbuf_append(&s, &l, ", commited=%d", notify_data->l3cd_changed.commited); + NM_HASH_OBFUSCATE_PTR_STR(notify_data->commit.l3cd_new, sbufobf)); + nm_strbuf_append(&s, &l, ", l3cd-changed=%d", notify_data->commit.l3cd_changed); break; case NM_L3_CONFIG_NOTIFY_TYPE_ACD_EVENT: nm_strbuf_append(&s, @@ -659,27 +661,22 @@ _nm_l3cfg_emit_signal_notify(NML3Cfg *self, const NML3ConfigNotifyData *notify_d } static void -_nm_l3cfg_emit_signal_notify_simple(NML3Cfg *self, NML3ConfigNotifyType notify_type) +_nm_l3cfg_emit_signal_notify_commit(NML3Cfg *self, + NML3ConfigNotifyType type, + const NML3ConfigData *l3cd_old, + const NML3ConfigData *l3cd_new, + gboolean l3cd_changed) { NML3ConfigNotifyData notify_data; - notify_data.notify_type = notify_type; - _nm_l3cfg_emit_signal_notify(self, ¬ify_data); -} - -static void -_nm_l3cfg_emit_signal_notify_l3cd_changed(NML3Cfg *self, - const NML3ConfigData *l3cd_old, - const NML3ConfigData *l3cd_new, - gboolean commited) -{ - NML3ConfigNotifyData notify_data; + nm_assert( + NM_IN_SET(type, NM_L3_CONFIG_NOTIFY_TYPE_PRE_COMMIT, NM_L3_CONFIG_NOTIFY_TYPE_POST_COMMIT)); - notify_data.notify_type = NM_L3_CONFIG_NOTIFY_TYPE_L3CD_CHANGED; - notify_data.l3cd_changed = (typeof(notify_data.l3cd_changed)){ - .l3cd_old = l3cd_old, - .l3cd_new = l3cd_new, - .commited = commited, + notify_data.notify_type = type; + notify_data.commit = (typeof(notify_data.commit)) { + .l3cd_old = l3cd_old, + .l3cd_new = l3cd_new, + .l3cd_changed = l3cd_changed, }; _nm_l3cfg_emit_signal_notify(self, ¬ify_data); } @@ -770,7 +767,7 @@ _nm_n_acd_data_probe_new(NML3Cfg *self, in_addr_t addr, guint32 timeout_msec, gp if (r) return NULL; - n_acd_probe_config_set_ip(probe_config, (struct in_addr){addr}); + n_acd_probe_config_set_ip(probe_config, (struct in_addr) {addr}); n_acd_probe_config_set_timeout(probe_config, timeout_msec); r = n_acd_probe(self->priv.p->nacd, &probe, probe_config); @@ -855,7 +852,7 @@ _obj_state_data_new(const NMPObject *obj, const NMPObject *plobj) ObjStateData *obj_state; obj_state = g_slice_new(ObjStateData); - *obj_state = (ObjStateData){ + *obj_state = (ObjStateData) { .obj = nmp_object_ref(obj), .os_plobj = nmp_object_ref(plobj), .os_was_in_platform = !!plobj, @@ -1581,7 +1578,7 @@ _nm_l3cfg_notify_platform_change_on_idle(NML3Cfg *self, guint32 obj_type_flags) _load_link(self, FALSE); notify_data.notify_type = NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE; - notify_data.platform_change_on_idle = (typeof(notify_data.platform_change_on_idle)){ + notify_data.platform_change_on_idle = (typeof(notify_data.platform_change_on_idle)) { .obj_type_flags = obj_type_flags, }; _nm_l3cfg_emit_signal_notify(self, ¬ify_data); @@ -1625,7 +1622,7 @@ _nm_l3cfg_notify_platform_change(NML3Cfg *self, } notify_data.notify_type = NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE; - notify_data.platform_change = (typeof(notify_data.platform_change)){ + notify_data.platform_change = (typeof(notify_data.platform_change)) { .obj = obj, .change_type = change_type, }; @@ -2161,7 +2158,7 @@ _l3_acd_data_add(NML3Cfg *self, } acd_data = g_slice_new(AcdData); - *acd_data = (AcdData){ + *acd_data = (AcdData) { .info = { .l3cfg = self, @@ -2193,7 +2190,7 @@ _l3_acd_data_add(NML3Cfg *self, } acd_track = (NML3AcdAddrTrackInfo *) &acd_data->info.track_infos[acd_data->info.n_track_infos++]; - *acd_track = (NML3AcdAddrTrackInfo){ + *acd_track = (NML3AcdAddrTrackInfo) { .l3cd = nm_l3_config_data_ref(l3cd), .obj = nmp_object_ref(obj), .tag = tag, @@ -2348,7 +2345,7 @@ _nm_l3cfg_emit_signal_notify_acd_event(NML3Cfg *self, AcdData *acd_data) nm_assert(acd_data->info.n_track_infos > 0); notify_data.notify_type = NM_L3_CONFIG_NOTIFY_TYPE_ACD_EVENT; - notify_data.acd_event = (typeof(notify_data.acd_event)){ + notify_data.acd_event = (typeof(notify_data.acd_event)) { .info = acd_data->info, }; @@ -3610,7 +3607,7 @@ nm_l3cfg_add_config(NML3Cfg *self, if (idx < 0) { l3_config_data = nm_g_array_append_new(self->priv.p->l3_config_datas, L3ConfigData); - *l3_config_data = (L3ConfigData){ + *l3_config_data = (L3ConfigData) { .tag_confdata = tag, .l3cd = nm_l3_config_data_ref_and_seal(l3cd), .config_flags = config_flags, @@ -3900,6 +3897,215 @@ out_ip4_address: } } +/*****************************************************************************/ + +static gboolean +_l3cfg_routed_dns_equal(GPtrArray *routes_old, GPtrArray *routes_new) +{ + guint i; + + if (nm_g_ptr_array_len(routes_old) != nm_g_ptr_array_len(routes_new)) + return FALSE; + + if (routes_old) { + nm_platform_route_objs_sort(routes_old, NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY); + } + + if (routes_new) { + nm_platform_route_objs_sort(routes_new, NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY); + } + + for (i = 0; i < nm_g_ptr_array_len(routes_old); i++) { + if (nmp_object_cmp(routes_old->pdata[i], routes_new->pdata[i]) != 0) + return FALSE; + } + + return TRUE; +} + +static GPtrArray * +_l3cfg_routed_dns_get_existing_routes(NML3Cfg *self, int addr_family) +{ + GPtrArray *routes = NULL; + NMPLookup lookup; + const NMDedupMultiHeadEntry *head_entry; + CList *iter; + + nmp_lookup_init_object_by_ifindex(&lookup, + NMP_OBJECT_TYPE_IP_ROUTE(NM_IS_IPv4(addr_family)), + self->priv.ifindex); + + head_entry = nm_platform_lookup(self->priv.platform, &lookup); + if (!head_entry) + return NULL; + + c_list_for_each (iter, &head_entry->lst_entries_head) { + const NMPObject *obj = c_list_entry(iter, NMDedupMultiEntry, lst_entries)->obj; + + if (nm_platform_route_table_uncoerce(obj->ipx_route.rx.table_coerced, FALSE) + != NM_DNS_ROUTES_FWMARK_TABLE_PRIO) + continue; + + if (!routes) + routes = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref); + g_ptr_array_add(routes, (gpointer) nmp_object_ref(obj)); + } + + return routes; +} + +static void +_l3cfg_routed_dns_apply(NML3Cfg *self, const NML3ConfigData *l3cd) +{ + if (!l3cd) + return; + + for (int IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) { + const char *const *nameservers; + guint i; + guint len; + int addr_family; + nm_auto_unref_ptrarray GPtrArray *old_routes = NULL; + nm_auto_unref_ptrarray GPtrArray *new_routes = NULL; + + addr_family = IS_IPv4 ? AF_INET : AF_INET6; + + if (!nm_l3_config_data_get_routed_dns(l3cd, addr_family)) + goto update_routes; + + _LOGT("configuring IPv%c DNS routes", nm_utils_addr_family_to_char(addr_family)); + + new_routes = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref); + + nameservers = nm_l3_config_data_get_nameservers(l3cd, addr_family, &len); + for (i = 0; i < len; i++) { + nm_auto_nmpobj NMPObject *obj = NULL; + NMPObject *obj_new; + const NMPlatformIPXRoute *route; + NMPlatformIPXRoute route_new; + char addr_buf[INET6_ADDRSTRLEN]; + char route_buf[128]; + NMDnsServer dns; + int r; + + if (!nm_dns_uri_parse(addr_family, nameservers[i], &dns)) + continue; + + /* Find the gateway to the DNS over the current interface. When + * doing the lookup, we want to ignore existing DNS routes added + * before: use policy routing with a special fwmark that skips + * the table containing DNS routes. */ + r = nm_platform_ip_route_get(self->priv.platform, + addr_family, + &dns.addr, + NM_DNS_ROUTES_FWMARK_TABLE_PRIO, + self->priv.ifindex, + &obj); + if (r < 0) { + _LOGD("could not get route to DNS server %s", + nm_inet_ntop(addr_family, dns.addr.addr_ptr, addr_buf)); + continue; + } + + route = NMP_OBJECT_CAST_IPX_ROUTE(obj); + + if (IS_IPv4) { + route_new.r4 = (NMPlatformIP4Route) { + .ifindex = self->priv.ifindex, + .network = dns.addr.addr4, + .plen = 32, + .table_any = FALSE, + .metric_any = TRUE, + .table_coerced = + nm_platform_route_table_coerce(NM_DNS_ROUTES_FWMARK_TABLE_PRIO), + .gateway = route->r4.gateway, + .rt_source = NM_IP_CONFIG_SOURCE_USER, + }; + + nm_platform_ip_route_normalize(addr_family, &route_new.rx); + + _LOGT("route to DNS server %s: %s", + nm_inet4_ntop(dns.addr.addr4, addr_buf), + nm_platform_ip4_route_to_string(&route_new.r4, route_buf, sizeof(route_buf))); + + obj_new = nmp_object_new(NMP_OBJECT_TYPE_IP4_ROUTE, &route_new); + g_ptr_array_add(new_routes, obj_new); + } else { + route_new.r6 = (NMPlatformIP6Route) { + .ifindex = self->priv.ifindex, + .network = dns.addr.addr6, + .plen = 128, + .table_any = FALSE, + .metric_any = TRUE, + .table_coerced = + nm_platform_route_table_coerce(NM_DNS_ROUTES_FWMARK_TABLE_PRIO), + .gateway = route->r6.gateway, + .rt_source = NM_IP_CONFIG_SOURCE_USER, + }; + + nm_platform_ip_route_normalize(addr_family, &route_new.rx); + + _LOGT("route to DNS server %s: %s", + nm_inet6_ntop(&dns.addr.addr6, addr_buf), + nm_platform_ip6_route_to_string(&route_new.r6, route_buf, sizeof(route_buf))); + + obj_new = nmp_object_new(NMP_OBJECT_TYPE_IP6_ROUTE, &route_new); + g_ptr_array_add(new_routes, obj_new); + } + } + + if (new_routes->len > 0) { + NMPlatformRoutingRule rule; + NMPObject rule_obj; + + /* Add a routing rule that selects the table when not using the + * special fwmark. Note that the rule is shared between all + * devices that use DNS routes. There is no cleanup mechanism: + * once added the rule stays forever. */ + rule = ((NMPlatformRoutingRule) { + .addr_family = addr_family, + .flags = FIB_RULE_INVERT, + .priority = NM_DNS_ROUTES_FWMARK_TABLE_PRIO, + .table = NM_DNS_ROUTES_FWMARK_TABLE_PRIO, + .fwmark = NM_DNS_ROUTES_FWMARK_TABLE_PRIO, + .fwmask = 0xffffffff, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_STATIC, + }); + + nmp_object_stackinit(&rule_obj, NMP_OBJECT_TYPE_ROUTING_RULE, &rule); + + if (!nm_platform_lookup_obj(self->priv.platform, + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + &rule_obj)) { + _LOGT("adding rule to DNS routing table"); + nm_platform_routing_rule_add(self->priv.platform, NMP_NLM_FLAG_ADD, &rule); + } + } + +update_routes: + old_routes = _l3cfg_routed_dns_get_existing_routes(self, addr_family); + + if (!_l3cfg_routed_dns_equal(old_routes, new_routes)) { + if (old_routes) { + _LOGT("deleting old DNS routes"); + for (i = 0; i < old_routes->len; i++) { + nm_platform_object_delete(self->priv.platform, old_routes->pdata[i]); + } + } + if (new_routes) { + _LOGT("adding new DNS routes"); + for (i = 0; i < new_routes->len; i++) { + nm_platform_ip_route_add(self->priv.platform, + NMP_NLM_FLAG_REPLACE, + new_routes->pdata[i], + NULL); + } + } + } + } +} + static void _l3cfg_update_combined_config(NML3Cfg *self, gboolean to_commit, @@ -4030,7 +4236,7 @@ _l3cfg_update_combined_config(NML3Cfg *self, nm_platform_ip6_address_init_loopback(&ax.a6)); } - rx.r4 = (NMPlatformIP4Route){ + rx.r4 = (NMPlatformIP4Route) { .ifindex = NM_LOOPBACK_IFINDEX, .rt_source = NM_IP_CONFIG_SOURCE_KERNEL, .network = NM_IPV4LO_ADDR1, @@ -4077,11 +4283,6 @@ _l3cfg_update_combined_config(NML3Cfg *self, self->priv.p->combined_l3cd_merged = nm_l3_config_data_seal(g_steal_pointer(&l3cd)); merged_changed = TRUE; - _nm_l3cfg_emit_signal_notify_l3cd_changed(self, - l3cd_old, - self->priv.p->combined_l3cd_merged, - FALSE); - if (!to_commit) { NM_SET_OUT(out_old, g_steal_pointer(&l3cd_old)); NM_SET_OUT(out_changed_combined_l3cd, TRUE); @@ -4096,11 +4297,6 @@ out: _obj_states_update_all(self); - _nm_l3cfg_emit_signal_notify_l3cd_changed(self, - l3cd_commited_old, - self->priv.p->combined_l3cd_commited, - TRUE); - NM_SET_OUT(out_old, g_steal_pointer(&l3cd_commited_old)); NM_SET_OUT(out_changed_combined_l3cd, TRUE); } @@ -4957,7 +5153,6 @@ static void _l3_commit_one(NML3Cfg *self, int addr_family, NML3CfgCommitType commit_type, - gboolean changed_combined_l3cd, const NML3ConfigData *l3cd_old) { const int IS_IPv4 = NM_IS_IPv4(addr_family); @@ -5192,10 +5387,16 @@ _l3_commit(NML3Cfg *self, NML3CfgCommitType commit_type, gboolean is_idle) &l3cd_old, &changed_combined_l3cd); - _nm_l3cfg_emit_signal_notify_simple(self, NM_L3_CONFIG_NOTIFY_TYPE_PRE_COMMIT); + _nm_l3cfg_emit_signal_notify_commit(self, + NM_L3_CONFIG_NOTIFY_TYPE_PRE_COMMIT, + l3cd_old, + self->priv.p->combined_l3cd_commited, + changed_combined_l3cd); + + _l3_commit_one(self, AF_INET, commit_type, l3cd_old); + _l3_commit_one(self, AF_INET6, commit_type, l3cd_old); - _l3_commit_one(self, AF_INET, commit_type, changed_combined_l3cd, l3cd_old); - _l3_commit_one(self, AF_INET6, commit_type, changed_combined_l3cd, l3cd_old); + _l3cfg_routed_dns_apply(self, self->priv.p->combined_l3cd_commited); _failedobj_reschedule(self, 0); @@ -5206,7 +5407,11 @@ _l3_commit(NML3Cfg *self, NML3CfgCommitType commit_type, gboolean is_idle) nm_assert(self->priv.p->commit_reentrant_count == 1); self->priv.p->commit_reentrant_count--; - _nm_l3cfg_emit_signal_notify_simple(self, NM_L3_CONFIG_NOTIFY_TYPE_POST_COMMIT); + _nm_l3cfg_emit_signal_notify_commit(self, + NM_L3_CONFIG_NOTIFY_TYPE_POST_COMMIT, + l3cd_old, + self->priv.p->combined_l3cd_commited, + changed_combined_l3cd); } NML3CfgBlockHandle * diff --git a/src/core/nm-l3cfg.h b/src/core/nm-l3cfg.h index 4d3537a0..5f0721da 100644 --- a/src/core/nm-l3cfg.h +++ b/src/core/nm-l3cfg.h @@ -24,6 +24,8 @@ #define NM_L3CFG_SIGNAL_NOTIFY "l3cfg-notify" +#define NM_DNS_ROUTES_FWMARK_TABLE_PRIO 20053 + typedef enum _nm_packed { _NM_L3_ACD_DEFEND_TYPE_NONE, NM_L3_ACD_DEFEND_TYPE_NEVER, @@ -123,22 +125,17 @@ nm_l3_acd_addr_info_find_track_info(const NML3AcdAddrInfo *addr_info, } typedef enum { - /* emitted when the merged/commited NML3ConfigData instance changes. + NM_L3_CONFIG_NOTIFY_TYPE_ACD_EVENT, + + /* Emitted before the merged l3cd is committed to platform. * Note that this gets emitted "under unsafe circumstances". That means, * you should not perform complex operations inside this callback, * and neither should you call into NML3Cfg again (reentrancy). */ - NM_L3_CONFIG_NOTIFY_TYPE_L3CD_CHANGED, - - NM_L3_CONFIG_NOTIFY_TYPE_ACD_EVENT, - - /* emitted before the merged l3cd is committed to platform. - * - * This event also gets emitted "under unsafe circumstances". - * See NM_L3_CONFIG_NOTIFY_TYPE_L3CD_CHANGED. */ NM_L3_CONFIG_NOTIFY_TYPE_PRE_COMMIT, /* emitted at the end of nm_l3cfg_platform_commit(). This signals also that - * nm_l3cfg_is_ready() might have switched to TRUE. */ + * nm_l3cfg_is_ready() might have switched to TRUE. Also emitted + * "under unsafe circumstances". */ NM_L3_CONFIG_NOTIFY_TYPE_POST_COMMIT, /* NML3Cfg hooks to the NMPlatform signals for link, addresses and routes. @@ -168,8 +165,8 @@ typedef struct { struct { const NML3ConfigData *l3cd_old; const NML3ConfigData *l3cd_new; - bool commited; - } l3cd_changed; + bool l3cd_changed; + } commit; struct { NML3AcdAddrInfo info; diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c index b96a9053..c9bcbd12 100644 --- a/src/core/nm-manager.c +++ b/src/core/nm-manager.c @@ -1638,7 +1638,7 @@ _devcon_lookup_data(NMManager *self, return NULL; data = g_slice_new(DevConData); - *data = (DevConData){ + *data = (DevConData) { .device = device, .sett_conn = sett_conn, .autoconnect = @@ -2522,7 +2522,7 @@ return_ifname_fom_connection: g_set_error(error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, - "failed to determine interface name: error determine name for %s", + "failed to determine interface name for a %s", nm_connection_get_connection_type(connection)); } return iface; @@ -3455,7 +3455,7 @@ get_existing_connection(NMManager *self, NMDevice *device, gboolean *out_generat if (connection) { NMConnection *con = nm_settings_connection_get_connection(connection_checked); - if (nm_utils_match_connection((NMConnection *[]){con, NULL}, + if (nm_utils_match_connection((NMConnection *[]) {con, NULL}, connection, TRUE, nm_device_has_carrier(device), @@ -4536,7 +4536,7 @@ nm_manager_get_best_device_for_connection(NMManager *self, NMSettingsConnection *sett_conn, NMConnection *connection, gboolean for_user_request, - GHashTable *unavailable_devices, + GHashTable *exclude_devices, GError **error) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self); @@ -4619,7 +4619,7 @@ nm_manager_get_best_device_for_connection(NMManager *self, ac_device = nm_active_connection_get_device(ac); if (ac_device - && ((unavailable_devices && g_hash_table_contains(unavailable_devices, ac_device)) + && (nm_g_hash_table_contains(exclude_devices, ac_device) || !nm_device_check_connection_available(ac_device, connection, flags, NULL, NULL))) ac_device = NULL; @@ -4635,9 +4635,7 @@ nm_manager_get_best_device_for_connection(NMManager *self, NMDevice *ac_device2 = nm_active_connection_get_device(ac2); NMActiveConnectionState ac_state2; - if (!ac_device2 - || (unavailable_devices - && g_hash_table_contains(unavailable_devices, ac_device2)) + if (!ac_device2 || nm_g_hash_table_contains(exclude_devices, ac_device2) || !nm_device_check_connection_available(ac_device2, connection, flags, @@ -4698,7 +4696,13 @@ found_better: GError *local = NULL; DeviceActivationPrio prio; - if (unavailable_devices && g_hash_table_contains(unavailable_devices, device)) + if (nm_g_hash_table_contains(exclude_devices, device)) + continue; + + if (!nm_device_is_available(device, + for_user_request + ? NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST + : NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) continue; /* determine the priority of this device. Currently, this priority is independent @@ -5347,7 +5351,7 @@ find_ports(NMManager *manager, } nm_assert(n_ports < n_all_connections); - ports[n_ports++] = (PortConnectionInfo){ + ports[n_ports++] = (PortConnectionInfo) { .connection = candidate, .device = port_device, }; @@ -6403,17 +6407,11 @@ nm_manager_activate_connection(NMManager *self, * @sett_conn: the #NMSettingsConnection to be activated, or %NULL if there * is only a partial activation. * @connection: the partial #NMConnection to be activated (if @sett_conn is unspecified) - * @device_path: the object path of the device to be activated, or NULL - * @out_device: on successful return, the #NMDevice to be activated with @connection - * The caller may pass in a device which shortcuts the lookup by path. - * In this case, the passed in device must have the matching @device_path - * already. - * @out_is_vpn: on successful return, %TRUE if @connection is a VPN connection * @error: location to store an error on failure * - * Performs basic validation on an activation request, including ensuring that - * the requestor is a valid Unix process, is not disallowed in @connection - * permissions, and that a device exists that can activate @connection. + * Performs basic permission validation on an activation request: Ensures that + * the requestor is a valid Unix process and is not disallowed in @connection + * permissions. * * Returns: on success, the #NMAuthSubject representing the requestor, or * %NULL on error @@ -6423,13 +6421,8 @@ validate_activation_request(NMManager *self, GDBusMethodInvocation *context, NMSettingsConnection *sett_conn, NMConnection *connection, - const char *device_path, - NMDevice **out_device, - gboolean *out_is_vpn, GError **error) { - NMDevice *device = NULL; - gboolean is_vpn = FALSE; gs_unref_object NMAuthSubject *subject = NULL; nm_assert(!sett_conn || NM_IS_SETTINGS_CONNECTION(sett_conn)); @@ -6437,8 +6430,6 @@ validate_activation_request(NMManager *self, nm_assert(sett_conn || connection); nm_assert(!connection || !sett_conn || connection == nm_settings_connection_get_connection(sett_conn)); - nm_assert(out_device); - nm_assert(out_is_vpn); if (!connection) connection = nm_settings_connection_get_connection(sett_conn); @@ -6459,6 +6450,51 @@ validate_activation_request(NMManager *self, NM_MANAGER_ERROR_PERMISSION_DENIED, error)) return NULL; + return g_steal_pointer(&subject); +} + +/** + * find_device_for_activation: + * @self: the #NMManager + * @sett_conn: the #NMSettingsConnection to be activated, or %NULL if there + * is only a partial activation. + * @connection: the partial #NMConnection to be activated (if @sett_conn is unspecified) + * @device_path: the object path of the device to be activated, or NULL + * @out_device: on successful return, the #NMDevice to be activated with @connection + * The caller may pass in a device which shortcuts the lookup by path. + * In this case, the passed in device must have the matching @device_path + * already. + * @out_is_vpn: on successful return, %TRUE if @connection is a VPN connection + * @error: location to store an error on failure + * + * Looks up a device that can activate @connection, or indicates the + * connection is a VPN connection that does not require a device. + * + * Returns: %TRUE if the device could be find or connection doesn't + * need one, %FALSE otherwise + */ +static gboolean +find_device_for_activation(NMManager *self, + NMSettingsConnection *sett_conn, + NMConnection *connection, + const char *device_path, + NMDevice **out_device, + gboolean *out_is_vpn, + GError **error) +{ + gboolean is_vpn = FALSE; + NMDevice *device = NULL; + + nm_assert(!sett_conn || NM_IS_SETTINGS_CONNECTION(sett_conn)); + nm_assert(!connection || NM_IS_CONNECTION(connection)); + nm_assert(sett_conn || connection); + nm_assert(!connection || !sett_conn + || connection == nm_settings_connection_get_connection(sett_conn)); + nm_assert(out_device); + nm_assert(out_is_vpn); + + if (!connection) + connection = nm_settings_connection_get_connection(sett_conn); is_vpn = _connection_is_vpn(connection); @@ -6475,7 +6511,7 @@ validate_activation_request(NMManager *self, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, "Device not found"); - return NULL; + return FALSE; } } else if (!is_vpn) { gs_free_error GError *local = NULL; @@ -6497,13 +6533,13 @@ validate_activation_request(NMManager *self, NM_MANAGER_ERROR_UNKNOWN_DEVICE, "No suitable device found for this connection (%s).", local->message); - return NULL; + return FALSE; } /* Look for an existing device with the connection's interface name */ iface = nm_manager_get_connection_iface(self, connection, NULL, NULL, error); if (!iface) - return NULL; + return FALSE; device = find_device_by_iface(self, iface, connection, NULL, NULL); if (!device) { @@ -6511,7 +6547,7 @@ validate_activation_request(NMManager *self, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, "Failed to find a compatible device for this connection"); - return NULL; + return FALSE; } } } @@ -6520,7 +6556,8 @@ validate_activation_request(NMManager *self, *out_device = device; *out_is_vpn = is_vpn; - return g_steal_pointer(&subject); + + return TRUE; } /*****************************************************************************/ @@ -6637,17 +6674,14 @@ impl_manager_activate_connection(NMDBusObject *obj, goto error; } - subject = validate_activation_request(self, - invocation, - sett_conn, - NULL, - device_path, - &device, - &is_vpn, - &error); + subject = validate_activation_request(self, invocation, sett_conn, NULL, &error); if (!subject) goto error; + if (!find_device_for_activation(self, sett_conn, NULL, device_path, &device, &is_vpn, &error)) { + goto error; + } + active = _new_active_connection(self, is_vpn, sett_conn, @@ -6920,17 +6954,20 @@ impl_manager_add_and_activate_connection(NMDBusObject *obj, NM_SETTING_PARSE_FLAGS_STRICT, NULL); - subject = validate_activation_request(self, - invocation, - NULL, - incompl_conn, - device_path, - &device, - &is_vpn, - &error); + subject = validate_activation_request(self, invocation, NULL, incompl_conn, &error); if (!subject) goto error; + if (!find_device_for_activation(self, + NULL, + incompl_conn, + device_path, + &device, + &is_vpn, + &error)) { + goto error; + } + if (is_vpn) { /* Try to fill the VPN's connection setting and name at least */ if (!nm_connection_get_setting_vpn(incompl_conn)) { @@ -6952,8 +6989,7 @@ impl_manager_add_and_activate_connection(NMDBusObject *obj, NULL, _("VPN connection"), NULL, - NULL, - FALSE); /* No IPv6 by default for now */ + NULL); } else { conns = nm_settings_connections_array_to_connections( nm_settings_get_connections(priv->settings, NULL), @@ -8931,12 +8967,12 @@ nm_manager_init(NMManager *self) priv->capabilities = g_array_new(FALSE, FALSE, sizeof(guint32)); - priv->radio_states[NM_RFKILL_TYPE_WLAN] = (RfkillRadioState){ + priv->radio_states[NM_RFKILL_TYPE_WLAN] = (RfkillRadioState) { .user_enabled = TRUE, .sw_enabled = FALSE, .hw_enabled = TRUE, }; - priv->radio_states[NM_RFKILL_TYPE_WWAN] = (RfkillRadioState){ + priv->radio_states[NM_RFKILL_TYPE_WWAN] = (RfkillRadioState) { .user_enabled = TRUE, .sw_enabled = FALSE, .hw_enabled = TRUE, diff --git a/src/core/nm-netns.c b/src/core/nm-netns.c index ed33d336..420d01e4 100644 --- a/src/core/nm-netns.c +++ b/src/core/nm-netns.c @@ -274,7 +274,7 @@ _ecmp_track_init_merged_obj(EcmpTrackEcmpid *track_ecmpid, const NMPObject **out const NMPlatformIP4Route *r = NMP_OBJECT_CAST_IP4_ROUTE(track_obj->obj); NMPlatformIP4RtNextHop *nh = (gpointer) &obj_new->_ip4_route.extra_nexthops[i - 1]; - *nh = (NMPlatformIP4RtNextHop){ + *nh = (NMPlatformIP4RtNextHop) { .ifindex = r->ifindex, .gateway = r->gateway, .weight = r->weight, @@ -620,7 +620,7 @@ nm_netns_shared_ip_reserve(NMNetns *self) } handle = g_slice_new(NMNetnsSharedIPHandle); - *handle = (NMNetnsSharedIPHandle){ + *handle = (NMNetnsSharedIPHandle) { .addr = addr, ._ref_count = 1, ._self = self, @@ -717,7 +717,7 @@ nm_netns_ip_route_ecmp_register(NMNetns *self, NML3Cfg *l3cfg, const NMPObject * track_ecmpid = g_hash_table_lookup(priv->ecmp_track_by_ecmpid, &obj); if (!track_ecmpid) { track_ecmpid = g_slice_new(EcmpTrackEcmpid); - *track_ecmpid = (EcmpTrackEcmpid){ + *track_ecmpid = (EcmpTrackEcmpid) { .representative_obj = nmp_object_ref(obj), .merged_obj = NULL, .ecmpid_lst_head = C_LIST_INIT(track_ecmpid->ecmpid_lst_head), @@ -728,7 +728,7 @@ nm_netns_ip_route_ecmp_register(NMNetns *self, NML3Cfg *l3cfg, const NMPObject * track_ecmpid->needs_update = TRUE; track_obj = g_slice_new(EcmpTrackObj); - *track_obj = (EcmpTrackObj){ + *track_obj = (EcmpTrackObj) { .obj = nmp_object_ref(obj), .l3cfg = l3cfg, .parent_track_ecmpid = track_ecmpid, @@ -1031,7 +1031,7 @@ _watcher_handle_init(NMNetnsWatcherHandle *handle, nm_assert(handle); nm_assert(NM_NETNS_WATCHER_TYPE_VALID(watcher_type)); - *handle = (NMNetnsWatcherHandle){ + *handle = (NMNetnsWatcherHandle) { .watcher_type = watcher_type, .tag = tag, .watcher_tag_lst = C_LIST_INIT(handle->watcher_tag_lst), @@ -1194,7 +1194,7 @@ _watcher_register_handle(NMNetns *self, NMNetnsWatcherHandle *handle) data = _watcher_ip_data_lookup_addr(self, &handle->watcher_data.ip_addr.addr); if (!data) { data = g_slice_new(WatcherDataIPAddr); - *data = (WatcherDataIPAddr){ + *data = (WatcherDataIPAddr) { .addr = handle->watcher_data.ip_addr.addr, .watcher_ip_addr_lst_head = C_LIST_INIT(data->watcher_ip_addr_lst_head), }; @@ -1288,7 +1288,7 @@ nm_netns_watcher_add(NMNetns *self, if (!watcher_by_tag) { watcher_by_tag = g_slice_new(WatcherByTag); - *watcher_by_tag = (WatcherByTag){ + *watcher_by_tag = (WatcherByTag) { .tag = tag, .watcher_by_tag_lst_head = C_LIST_INIT(watcher_by_tag->watcher_by_tag_lst_head), }; diff --git a/src/core/nm-pacrunner-manager.c b/src/core/nm-pacrunner-manager.c index 80db755f..12c3c9a1 100644 --- a/src/core/nm-pacrunner-manager.c +++ b/src/core/nm-pacrunner-manager.c @@ -365,7 +365,7 @@ nm_pacrunner_manager_add(NMPacrunnerManager *self, const char *iface, const NML3 priv = NM_PACRUNNER_MANAGER_GET_PRIVATE(self); conf_id = g_slice_new(NMPacrunnerConfId); - *conf_id = (NMPacrunnerConfId){ + *conf_id = (NMPacrunnerConfId) { .log_id = ++priv->log_id_counter, .refcount = 1, .self = g_object_ref(self), diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c index 05d4d006..f86d8115 100644 --- a/src/core/nm-policy.c +++ b/src/core/nm-policy.c @@ -824,7 +824,7 @@ build_device_hostname_infos(NMPolicy *self) array = g_array_sized_new(FALSE, FALSE, sizeof(DeviceHostnameInfo), 4); info = nm_g_array_append_new(array, DeviceHostnameInfo); - *info = (DeviceHostnameInfo){ + *info = (DeviceHostnameInfo) { .device = device, .priority = device_get_hostname_priority(device), .from_dhcp = @@ -2448,6 +2448,10 @@ device_l3cd_changed(NMDevice *device, */ state = nm_device_get_state(device); if (l3cd_new && state >= NM_DEVICE_STATE_IP_CONFIG && state < NM_DEVICE_STATE_DEACTIVATING) { + /* Since the device L3CD_CHANGED signal is emitted *after* the commit of + * configuration, addresses and routes are already set in kernel when we + * write the configuration to resolv.conf or send it to the DNS plugin. + * This prevents "leaks" of DNS queries via the wrong routes.*/ nm_dns_manager_set_ip_config(priv->dns_manager, AF_UNSPEC, device, diff --git a/src/core/nm-rfkill-manager.c b/src/core/nm-rfkill-manager.c index aea5df11..c8efc376 100644 --- a/src/core/nm-rfkill-manager.c +++ b/src/core/nm-rfkill-manager.c @@ -146,7 +146,7 @@ killswitch_new(struct udev_device *device, NMRfkillType rtype) platform = TRUE; ks = g_slice_new(Killswitch); - *ks = (Killswitch){ + *ks = (Killswitch) { .name = g_strdup(udev_device_get_sysname(device)), .seqnum = udev_device_get_seqnum(device), .path = g_strdup(udev_device_get_syspath(device)), diff --git a/src/core/platform/nm-fake-platform.c b/src/core/platform/nm-fake-platform.c index 6a64746e..10c69f63 100644 --- a/src/core/platform/nm-fake-platform.c +++ b/src/core/platform/nm-fake-platform.c @@ -1000,7 +1000,7 @@ ip4_address_add(NMPlatform *platform, { NMPlatformIP4Address address; - address = (NMPlatformIP4Address){ + address = (NMPlatformIP4Address) { .addr_source = NM_IP_CONFIG_SOURCE_KERNEL, .ifindex = ifindex, .address = addr, diff --git a/src/core/platform/tests/test-common.c b/src/core/platform/tests/test-common.c index 99b8bc45..26f8b26b 100644 --- a/src/core/platform/tests/test-common.c +++ b/src/core/platform/tests/test-common.c @@ -224,7 +224,7 @@ _nmtstp_platform_ip_addresses_assert(const char *filename, else g_error("%s:%d: invalid IP address in argument: %s", filename, lineno, addrstr); - addrs_bin[i] = (IPAddressesAssertData){ + addrs_bin[i] = (IPAddressesAssertData) { .addr_family = addr_family, .addr = a, .found = FALSE, @@ -1117,7 +1117,7 @@ again: link = nmtstp_link_gre_add(NULL, EX, test_ifname, - &((const NMPlatformLnkGre){ + &((const NMPlatformLnkGre) { .local = nmtst_inet4_from_string("192.168.233.204"), .remote = nmtst_inet4_from_string("172.168.10.25"), .parent_ifindex = 0, @@ -1129,7 +1129,7 @@ again: link = nmtstp_link_ipip_add(NULL, EX, test_ifname, - &((const NMPlatformLnkIpIp){ + &((const NMPlatformLnkIpIp) { .local = nmtst_inet4_from_string("1.2.3.4"), .remote = nmtst_inet4_from_string("5.6.7.8"), .parent_ifindex = 0, @@ -1140,7 +1140,7 @@ again: link = nmtstp_link_ip6tnl_add(NULL, EX, test_ifname, - &((const NMPlatformLnkIp6Tnl){ + &((const NMPlatformLnkIp6Tnl) { .local = nmtst_inet6_from_string("fd01::15"), .remote = nmtst_inet6_from_string("fd01::16"), .tclass = 20, @@ -1152,7 +1152,7 @@ again: link = nmtstp_link_ip6gre_add(NULL, EX, test_ifname, - &((const NMPlatformLnkIp6Tnl){ + &((const NMPlatformLnkIp6Tnl) { .local = nmtst_inet6_from_string("fd01::42"), .remote = nmtst_inet6_from_string("fd01::aaaa"), .tclass = 21, @@ -1163,7 +1163,7 @@ again: link = nmtstp_link_sit_add(NULL, EX, test_ifname, - &((const NMPlatformLnkSit){ + &((const NMPlatformLnkSit) { .local = nmtst_inet4_from_string("192.168.200.1"), .remote = nmtst_inet4_from_string("172.25.100.14"), .ttl = 0, @@ -1174,7 +1174,7 @@ again: link = nmtstp_link_vti_add(NULL, EX, test_ifname, - &((const NMPlatformLnkVti){ + &((const NMPlatformLnkVti) { .local = nmtst_inet4_from_string("192.168.212.204"), .remote = nmtst_inet4_from_string("172.168.11.25"), .ikey = 12, @@ -1184,7 +1184,7 @@ again: link = nmtstp_link_vti6_add(NULL, EX, test_ifname, - &((const NMPlatformLnkVti6){ + &((const NMPlatformLnkVti6) { .local = nmtst_inet6_from_string("fd01::1"), .remote = nmtst_inet6_from_string("fd02::2"), .ikey = 13, @@ -1891,11 +1891,11 @@ nmtstp_ip4_address_add(NMPlatform *platform, external_command, TRUE, ifindex, - &((NMIPAddr){ + &((NMIPAddr) { .addr4 = address, }), plen, - &((NMIPAddr){ + &((NMIPAddr) { .addr4 = peer_address, }), lifetime, @@ -3592,7 +3592,7 @@ nmtstp_acd_defender_new(int ifindex, in_addr_t ip_addr, const NMEtherAddr *mac_a g_assert_cmpint(r, ==, 0); g_assert(probe_config); - n_acd_probe_config_set_ip(probe_config, (struct in_addr){ip_addr}); + n_acd_probe_config_set_ip(probe_config, (struct in_addr) {ip_addr}); n_acd_probe_config_set_timeout(probe_config, 0); r = n_acd_probe(nacd, &probe, probe_config); @@ -3600,7 +3600,7 @@ nmtstp_acd_defender_new(int ifindex, in_addr_t ip_addr, const NMEtherAddr *mac_a g_assert(probe); defender = g_slice_new(NMTstpAcdDefender); - *defender = (NMTstpAcdDefender){ + *defender = (NMTstpAcdDefender) { .ifindex = ifindex, .ip_addr = ip_addr, .nacd = g_steal_pointer(&nacd), diff --git a/src/core/platform/tests/test-common.h b/src/core/platform/tests/test-common.h index 12d6e7ce..85ed7961 100644 --- a/src/core/platform/tests/test-common.h +++ b/src/core/platform/tests/test-common.h @@ -372,21 +372,21 @@ void _nmtstp_platform_ip_addresses_assert(const char *filename, guint addrs_len, const char *const *addrs); -#define nmtstp_platform_ip_addresses_assert(self, \ - ifindex, \ - force_exact_4, \ - force_exact_6, \ - ignore_ll6, \ - ...) \ - _nmtstp_platform_ip_addresses_assert(__FILE__, \ - __LINE__, \ - (self), \ - (ifindex), \ - (force_exact_4), \ - (force_exact_6), \ - (ignore_ll6), \ - NM_NARG(__VA_ARGS__), \ - ((const char *const[]){"dummy", ##__VA_ARGS__, NULL}) \ +#define nmtstp_platform_ip_addresses_assert(self, \ + ifindex, \ + force_exact_4, \ + force_exact_6, \ + ignore_ll6, \ + ...) \ + _nmtstp_platform_ip_addresses_assert(__FILE__, \ + __LINE__, \ + (self), \ + (ifindex), \ + (force_exact_4), \ + (force_exact_6), \ + (ignore_ll6), \ + NM_NARG(__VA_ARGS__), \ + ((const char *const[]) {"dummy", ##__VA_ARGS__, NULL}) \ + 1) /*****************************************************************************/ @@ -540,7 +540,7 @@ gboolean nmtstp_ensure_module(const char *module_name); /*****************************************************************************/ #define nmtst_object_new_mptcp_addr(...) \ - nmp_object_new(NMP_OBJECT_TYPE_MPTCP_ADDR, &((const NMPlatformMptcpAddr){__VA_ARGS__})) + nmp_object_new(NMP_OBJECT_TYPE_MPTCP_ADDR, &((const NMPlatformMptcpAddr) {__VA_ARGS__})) /*****************************************************************************/ diff --git a/src/core/platform/tests/test-link.c b/src/core/platform/tests/test-link.c index bcb135d3..4cadfe4d 100644 --- a/src/core/platform/tests/test-link.c +++ b/src/core/platform/tests/test-link.c @@ -174,7 +174,7 @@ software_add(NMLinkType link_type, const char *name) return NMTST_NM_ERR_SUCCESS(nm_platform_link_vlan_add(NM_PLATFORM_GET, name, parent_ifindex, - &((NMPlatformLnkVlan){ + &((NMPlatformLnkVlan) { .id = VLAN_ID, .protocol = ETH_P_8021Q, }), @@ -289,7 +289,7 @@ test_port(int controller, int port_type, SignalData *controller_changed) prio_supported = (lnk->mode == 1); prio_has = nmtst_get_rand_bool() && prio_supported; - bond_port = (NMPlatformLinkBondPort){ + bond_port = (NMPlatformLinkBondPort) { .queue_id = 5, .prio_has = prio_has, .prio = prio_has ? 6 : 0, @@ -315,7 +315,7 @@ test_port(int controller, int port_type, SignalData *controller_changed) lnk = nm_platform_link_get_lnk_bridge(NM_PLATFORM_GET, controller, NULL); g_assert(lnk); - bridge_port = (NMPlatformLinkBridgePort){ + bridge_port = (NMPlatformLinkBridgePort) { .path_cost = 100, .priority = 614, .hairpin = 0, @@ -724,7 +724,7 @@ test_bridge_addr(void) g_assert_cmpint(plink->l_address.len, ==, sizeof(addr)); g_assert(!memcmp(plink->l_address.data, addr, sizeof(addr))); - info_data = (const NMPlatformLinkSetBridgeInfoData){ + info_data = (const NMPlatformLinkSetBridgeInfoData) { .vlan_default_pvid_val = nmtst_rand_select(0, 5, 42, 1048), .vlan_default_pvid_has = nmtst_get_rand_bool(), .vlan_filtering_val = nmtst_get_rand_bool(), @@ -743,7 +743,7 @@ test_bridge_addr(void) "/sys/class/net/" DEVICE_NAME "/bridge/vlan_filtering", info_data.vlan_filtering_val && info_data.vlan_filtering_has ? "1" : "0"); - info_data = (const NMPlatformLinkSetBridgeInfoData){ + info_data = (const NMPlatformLinkSetBridgeInfoData) { .vlan_default_pvid_val = 55, .vlan_default_pvid_has = TRUE, .vlan_filtering_val = !info_data.vlan_filtering_val, @@ -1275,7 +1275,7 @@ _test_wireguard_change(NMPlatform *platform, int ifindex, int test_mode) peers = g_array_new(FALSE, TRUE, sizeof(NMPWireGuardPeer)); - lnk_wireguard = (NMPlatformLnkWireGuard){ + lnk_wireguard = (NMPlatformLnkWireGuard) { .listen_port = 50754, .fwmark = 0x1102, }; @@ -1295,7 +1295,7 @@ _test_wireguard_change(NMPlatform *platform, int ifindex, int test_mode) NMPWireGuardAllowedIP *allowed_ips; if ((i % 2) == 1) { - endpoint = (NMSockAddrUnion){ + endpoint = (NMSockAddrUnion) { .in = { .sin_family = AF_INET, @@ -1305,7 +1305,7 @@ _test_wireguard_change(NMPlatform *platform, int ifindex, int test_mode) }, }; } else { - endpoint = (NMSockAddrUnion){ + endpoint = (NMSockAddrUnion) { .in6 = { .sin6_family = AF_INET6, @@ -1337,7 +1337,7 @@ _test_wireguard_change(NMPlatform *platform, int ifindex, int test_mode) } } - peer = (NMPWireGuardPeer){ + peer = (NMPWireGuardPeer) { .persistent_keepalive_interval = 60 + i, .endpoint = endpoint, .allowed_ips = n_allowed_ips > 0 ? allowed_ips : NULL, @@ -1803,7 +1803,7 @@ test_software_detect(gconstpointer user_data) switch (test_data->test_mode) { case 0: - lnk_tun = (NMPlatformLnkTun){ + lnk_tun = (NMPlatformLnkTun) { .type = nmtst_get_rand_bool() ? IFF_TUN : IFF_TAP, .owner = owner_valid ? getuid() : 0, .owner_valid = owner_valid, @@ -2702,7 +2702,7 @@ test_link_set_properties(void) NMPlatformLinkChangeFlags flags; int ifindex; - props = (NMPlatformLinkProps){ + props = (NMPlatformLinkProps) { .tx_queue_length = 599, .gso_max_size = 10001, .gso_max_segments = 512, @@ -3814,7 +3814,7 @@ test_sysctl_set_async(void) cancellable = g_cancellable_new(); proc_writable = access(PATH, W_OK) == 0; - data = (SetAsyncData){ + data = (SetAsyncData) { .loop = loop, .path = PATH, .expected_success = proc_writable, @@ -3823,7 +3823,7 @@ test_sysctl_set_async(void) nm_platform_sysctl_set_async(PL, NMP_SYSCTL_PATHID_ABSOLUTE(PATH), - (const char *[]){"2", NULL}, + (const char *[]) {"2", NULL}, sysctl_set_async_cb, &data, cancellable); @@ -3831,7 +3831,7 @@ test_sysctl_set_async(void) if (!nmtst_main_loop_run(loop, 1000)) g_assert_not_reached(); - data = (SetAsyncData){ + data = (SetAsyncData) { .loop = loop, .path = PATH, .expected_success = proc_writable, @@ -3840,7 +3840,7 @@ test_sysctl_set_async(void) nm_platform_sysctl_set_async(PL, NMP_SYSCTL_PATHID_ABSOLUTE(PATH), - (const char *[]){"2", "0", "1", "0", "1", NULL}, + (const char *[]) {"2", "0", "1", "0", "1", NULL}, sysctl_set_async_cb, &data, cancellable); @@ -3867,7 +3867,7 @@ test_sysctl_set_async_fail(void) loop = g_main_loop_new(NULL, FALSE); cancellable = g_cancellable_new(); - data = (SetAsyncData){ + data = (SetAsyncData) { .loop = loop, .path = PATH, .expected_success = FALSE, @@ -3875,7 +3875,7 @@ test_sysctl_set_async_fail(void) nm_platform_sysctl_set_async(PL, NMP_SYSCTL_PATHID_ABSOLUTE(PATH), - (const char *[]){"2", NULL}, + (const char *[]) {"2", NULL}, sysctl_set_async_cb, &data, cancellable); diff --git a/src/core/platform/tests/test-route.c b/src/core/platform/tests/test-route.c index 9aa21a9a..a05362f2 100644 --- a/src/core/platform/tests/test-route.c +++ b/src/core/platform/tests/test-route.c @@ -574,6 +574,7 @@ test_ip4_route_get(void) result = nm_platform_ip_route_get(NM_PLATFORM_GET, AF_INET, &a, + 0, nmtst_get_rand_uint32() % 2 ? 0 : ifindex, &route); @@ -638,7 +639,7 @@ test_ip4_route_options(gconstpointer test_data) switch (TEST_IDX) { case 1: - rts_add[rts_n++] = ((NMPlatformIP4Route){ + rts_add[rts_n++] = ((NMPlatformIP4Route) { .ifindex = IFINDEX, .rt_source = NM_IP_CONFIG_SOURCE_USER, .network = nmtst_inet4_from_string("172.16.1.0"), @@ -658,7 +659,7 @@ test_ip4_route_options(gconstpointer test_data) }); break; case 2: - addr[addr_n++] = ((NMPlatformIP4Address){ + addr[addr_n++] = ((NMPlatformIP4Address) { .ifindex = IFINDEX, .address = nmtst_inet4_from_string("172.16.1.5"), .peer_address = nmtst_inet4_from_string("172.16.1.5"), @@ -667,7 +668,7 @@ test_ip4_route_options(gconstpointer test_data) .preferred = NM_PLATFORM_LIFETIME_PERMANENT, .n_ifa_flags = 0, }); - rts_add[rts_n++] = ((NMPlatformIP4Route){ + rts_add[rts_n++] = ((NMPlatformIP4Route) { .ifindex = IFINDEX, .rt_source = NM_IP_CONFIG_SOURCE_USER, .network = nmtst_inet4_from_string("172.17.1.0"), @@ -676,7 +677,7 @@ test_ip4_route_options(gconstpointer test_data) .metric = 20, .n_nexthops = 1, }); - rts_add[rts_n++] = ((NMPlatformIP4Route){ + rts_add[rts_n++] = ((NMPlatformIP4Route) { .ifindex = IFINDEX, .rt_source = NM_IP_CONFIG_SOURCE_USER, .network = nmtst_inet4_from_string("172.19.1.0"), @@ -766,6 +767,7 @@ test_ip6_route_get(void) result = nm_platform_ip_route_get(NM_PLATFORM_GET, AF_INET6, a, + 0, nmtst_get_rand_uint32() % 2 ? 0 : ifindex, &route); @@ -801,7 +803,7 @@ test_ip6_route_options(gconstpointer test_data) switch (TEST_IDX) { case 1: - rts_add[rts_n++] = ((NMPlatformIP6Route){ + rts_add[rts_n++] = ((NMPlatformIP6Route) { .ifindex = IFINDEX, .rt_source = NM_IP_CONFIG_SOURCE_USER, .network = nmtst_inet6_from_string("2001:db8:a:b:0:0:0:0"), @@ -817,7 +819,7 @@ test_ip6_route_options(gconstpointer test_data) }); break; case 2: - addr[addr_n++] = ((NMPlatformIP6Address){ + addr[addr_n++] = ((NMPlatformIP6Address) { .ifindex = IFINDEX, .address = nmtst_inet6_from_string("2000::2"), .plen = 128, @@ -826,7 +828,7 @@ test_ip6_route_options(gconstpointer test_data) .preferred = NM_PLATFORM_LIFETIME_PERMANENT, .n_ifa_flags = 0, }); - rts_add[rts_n++] = ((NMPlatformIP6Route){ + rts_add[rts_n++] = ((NMPlatformIP6Route) { .ifindex = IFINDEX, .rt_source = NM_IP_CONFIG_SOURCE_USER, .network = nmtst_inet6_from_string("1010::1"), @@ -837,7 +839,7 @@ test_ip6_route_options(gconstpointer test_data) }); break; case 3: - addr[addr_n++] = ((NMPlatformIP6Address){ + addr[addr_n++] = ((NMPlatformIP6Address) { .ifindex = IFINDEX, .address = nmtst_inet6_from_string("2001:db8:8086::5"), .plen = 128, @@ -846,7 +848,7 @@ test_ip6_route_options(gconstpointer test_data) .preferred = NM_PLATFORM_LIFETIME_PERMANENT, .n_ifa_flags = 0, }); - rts_add[rts_n++] = ((NMPlatformIP6Route){ + rts_add[rts_n++] = ((NMPlatformIP6Route) { .ifindex = IFINDEX, .rt_source = nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER), .network = nmtst_inet6_from_string("2001:db8:8086::"), @@ -854,7 +856,7 @@ test_ip6_route_options(gconstpointer test_data) .metric = 10021, .mss = 0, }); - rts_add[rts_n++] = ((NMPlatformIP6Route){ + rts_add[rts_n++] = ((NMPlatformIP6Route) { .ifindex = IFINDEX, .rt_source = nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER), .network = nmtst_inet6_from_string("2001:db8:abad:c0de::"), @@ -1595,7 +1597,7 @@ test_rule(gconstpointer test_data) #define RR(...) \ nmp_object_new(NMP_OBJECT_TYPE_ROUTING_RULE, \ - (const NMPlatformObject *) &((NMPlatformRoutingRule){__VA_ARGS__})) + (const NMPlatformObject *) &((NMPlatformRoutingRule) {__VA_ARGS__})) objs = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref); @@ -1926,11 +1928,11 @@ test_blackhole(gconstpointer test_data) rtn_type = nmtst_rand_select(RTN_BLACKHOLE, RTN_UNREACHABLE, RTN_PROHIBIT, RTN_THROW); if (IS_IPv4) { - rr.r4 = (const NMPlatformIP4Route){ + rr.r4 = (const NMPlatformIP4Route) { .type_coerced = nm_platform_route_type_coerce(rtn_type), }; } else { - rr.r6 = (const NMPlatformIP6Route){ + rr.r6 = (const NMPlatformIP6Route) { .type_coerced = nm_platform_route_type_coerce(rtn_type), .metric = 1000, }; @@ -1987,7 +1989,7 @@ again: if (p == -1) { static gsize lock; - const NMPlatformMptcpAddr mptcp_addr = (NMPlatformMptcpAddr){ + const NMPlatformMptcpAddr mptcp_addr = (NMPlatformMptcpAddr) { .id = 1, .addr_family = AF_INET, .addr.addr4 = nmtst_inet4_from_string("1.2.3.4"), diff --git a/src/core/platform/tests/test-tc.c b/src/core/platform/tests/test-tc.c index 832fbea6..dc4dafc0 100644 --- a/src/core/platform/tests/test-tc.c +++ b/src/core/platform/tests/test-tc.c @@ -16,7 +16,7 @@ qdisc_new(int ifindex, const char *kind, guint32 parent) NMPObject *obj; obj = nmp_object_new(NMP_OBJECT_TYPE_QDISC, NULL); - obj->qdisc = (NMPlatformQdisc){ + obj->qdisc = (NMPlatformQdisc) { .ifindex = ifindex, .kind = kind, .parent = parent, diff --git a/src/core/ppp/nm-ppp-manager.c b/src/core/ppp/nm-ppp-manager.c index fbc5d075..2eebd17d 100644 --- a/src/core/ppp/nm-ppp-manager.c +++ b/src/core/ppp/nm-ppp-manager.c @@ -547,7 +547,7 @@ impl_ppp_manager_set_ip4_config(NMDBusObject *obj, nm_l3_config_data_set_mtu(l3cd, mtu); - address = (NMPlatformIP4Address){ + address = (NMPlatformIP4Address) { .plen = 32, }; @@ -583,7 +583,7 @@ impl_ppp_manager_set_ip4_config(NMDBusObject *obj, if (g_variant_lookup(config_dict, NM_PPP_IP4_CONFIG_DNS, "au", &iter)) { while (g_variant_iter_next(iter, "u", &u32)) - nm_l3_config_data_add_nameserver_detail(l3cd, AF_INET, &u32, NULL); + nm_l3_config_data_add_nameserver_addr(l3cd, AF_INET, &u32); g_variant_iter_free(iter); } @@ -662,7 +662,7 @@ impl_ppp_manager_set_ip6_config(NMDBusObject *obj, nm_l3_config_data_set_mtu(l3cd, mtu); - address = (NMPlatformIP6Address){ + address = (NMPlatformIP6Address) { .plen = 64, .addr_source = NM_IP_CONFIG_SOURCE_PPP, }; diff --git a/src/core/ppp/nm-ppp-mgr.c b/src/core/ppp/nm-ppp-mgr.c index 91d9a021..9f6e8835 100644 --- a/src/core/ppp/nm-ppp-mgr.c +++ b/src/core/ppp/nm-ppp-mgr.c @@ -208,11 +208,11 @@ _set_state_failed(NMPppMgr *self, NMPppMgrState state, NMPppMgrState *out_old_st self->ifindex = 0; nm_clear_l3cd(&self->ip_data_4.l3cd); nm_clear_l3cd(&self->ip_data_6.l3cd); - self->ip_data_4 = (NMPppMgrIPData){ + self->ip_data_4 = (NMPppMgrIPData) { .ip_received = FALSE, .ip_enabled = FALSE, }; - self->ip_data_6 = (NMPppMgrIPData){ + self->ip_data_6 = (NMPppMgrIPData) { .ip_received = FALSE, .ip_enabled = FALSE, }; @@ -563,7 +563,7 @@ nm_ppp_mgr_start(const NMPppMgrConfig *config, GError **error) self = g_slice_new(NMPppMgr); - *self = (NMPppMgr){ + *self = (NMPppMgr) { .config = *config, .ppp_manager = ppp_manager, .idle_start = nm_g_idle_add_source(_idle_start_cb, self), diff --git a/src/core/ppp/nm-pppd-compat.c b/src/core/ppp/nm-pppd-compat.c index 04e26f22..c1416023 100644 --- a/src/core/ppp/nm-pppd-compat.c +++ b/src/core/ppp/nm-pppd-compat.c @@ -164,14 +164,14 @@ nm_pppd_compat_get_ipcp_options(NMPppdCompatIPCPOptions *out_got, NMPppdCompatIP nm_assert(out_got); nm_assert(out_his); - *out_got = (NMPppdCompatIPCPOptions){ + *out_got = (NMPppdCompatIPCPOptions) { .ouraddr = got->ouraddr, .hisaddr = got->hisaddr, .dnsaddr = {got->dnsaddr[0], got->dnsaddr[1]}, .winsaddr = {got->winsaddr[0], got->winsaddr[1]}, }; - *out_his = (NMPppdCompatIPCPOptions){ + *out_his = (NMPppdCompatIPCPOptions) { .ouraddr = his->ouraddr, .hisaddr = his->hisaddr, .dnsaddr = {his->dnsaddr[0], his->dnsaddr[1]}, @@ -191,11 +191,11 @@ nm_pppd_compat_get_ipv6cp_options(NMPppdCompatIPV6CPOptions *out_got, nm_assert(out_got); nm_assert(out_his); - *out_got = (NMPppdCompatIPV6CPOptions){}; + *out_got = (NMPppdCompatIPV6CPOptions) {}; memcpy(&out_got->ourid, &got->ourid, sizeof(guint64)); memcpy(&out_got->hisid, &got->hisid, sizeof(guint64)); - *out_his = (NMPppdCompatIPV6CPOptions){}; + *out_his = (NMPppdCompatIPV6CPOptions) {}; memcpy(&out_his->ourid, &his->ourid, sizeof(guint64)); memcpy(&out_his->hisid, &his->hisid, sizeof(guint64)); } diff --git a/src/core/settings/nm-secret-agent.c b/src/core/settings/nm-secret-agent.c index bb300345..6448ec57 100644 --- a/src/core/settings/nm-secret-agent.c +++ b/src/core/settings/nm-secret-agent.c @@ -142,7 +142,7 @@ _call_id_new(NMSecretAgent *self, NMSecretAgentCallId *call_id; call_id = g_slice_new(NMSecretAgentCallId); - *call_id = (NMSecretAgentCallId){ + *call_id = (NMSecretAgentCallId) { .self = g_object_ref(self), .path = g_strdup(path), .setting_name = g_strdup(setting_name), diff --git a/src/core/settings/nm-settings-connection.c b/src/core/settings/nm-settings-connection.c index 459c60ad..d5611e76 100644 --- a/src/core/settings/nm-settings-connection.c +++ b/src/core/settings/nm-settings-connection.c @@ -1721,7 +1721,7 @@ settings_connection_update(NMSettingsConnection *self, goto error; info = g_slice_new(UpdateInfo); - *info = (UpdateInfo){ + *info = (UpdateInfo) { .is_update2 = is_update2, .context = context, .agent_mgr = g_object_ref(priv->agent_mgr), diff --git a/src/core/settings/nm-settings-plugin.c b/src/core/settings/nm-settings-plugin.c index 60181759..5dae482f 100644 --- a/src/core/settings/nm-settings-plugin.c +++ b/src/core/settings/nm-settings-plugin.c @@ -110,7 +110,7 @@ nm_settings_plugin_create_connection_load_entries(const char *const *filenames, entries = g_new(NMSettingsPluginConnectionLoadEntry, len); for (i = 0; i < len; i++) { - entries[i] = (NMSettingsPluginConnectionLoadEntry){ + entries[i] = (NMSettingsPluginConnectionLoadEntry) { .filename = filenames[i], .error = NULL, .handled = FALSE, diff --git a/src/core/settings/nm-settings-utils.c b/src/core/settings/nm-settings-utils.c index 4343a376..820d4fbd 100644 --- a/src/core/settings/nm-settings-utils.c +++ b/src/core/settings/nm-settings-utils.c @@ -37,14 +37,14 @@ nm_sett_util_stat_mtime(const char *filename, gboolean do_lstat, struct timespec } if (gettimeofday(&now_tv, NULL) == 0) { - *out_val = (struct timespec){ + *out_val = (struct timespec) { .tv_sec = now_tv.tv_sec, .tv_nsec = now_tv.tv_usec * 1000u, }; return out_val; } - *out_val = (struct timespec){}; + *out_val = (struct timespec) {}; return out_val; } diff --git a/src/core/settings/nm-settings-utils.h b/src/core/settings/nm-settings-utils.h index d3f50ddf..949963e2 100644 --- a/src/core/settings/nm-settings-utils.h +++ b/src/core/settings/nm-settings-utils.h @@ -81,7 +81,7 @@ typedef struct { } NMSettUtilAllowFilenameData; #define NM_SETT_UTIL_ALLOW_FILENAME_DATA(_storages, _allowed_filename) \ - (&((NMSettUtilAllowFilenameData){ \ + (&((NMSettUtilAllowFilenameData) { \ .idx_by_filename = (_storages)->idx_by_filename, \ .allowed_filename = (_allowed_filename), \ })) diff --git a/src/core/settings/nm-settings.c b/src/core/settings/nm-settings.c index 80b1f4b2..50d98ece 100644 --- a/src/core/settings/nm-settings.c +++ b/src/core/settings/nm-settings.c @@ -703,7 +703,7 @@ _startup_complete_notify_connection(NMSettings *self, if (timeout_msec == 0) return; scd = g_slice_new(StartupCompleteData); - *scd = (StartupCompleteData){ + *scd = (StartupCompleteData) { .sett_conn = g_object_ref(sett_conn), .timeout_msec = timeout_msec, }; diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index 81964de6..d64052cb 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -2056,9 +2056,8 @@ make_ip4_setting(shvarFile *ifcfg, * Pick up just IPv4 addresses (IPv6 addresses are taken by make_ip6_setting()) */ for (i = 1; i < 10000; i++) { - int af; - NMIPAddr ip; - char tag[256]; + NMDnsServer dns; + char tag[256]; numbered_tag(tag, "DNS", i); nm_clear_g_free(&value); @@ -2066,14 +2065,16 @@ make_ip4_setting(shvarFile *ifcfg, if (!v) break; - if (!nm_utils_dnsname_parse(AF_UNSPEC, v, &af, &ip, NULL)) { + if (!nm_dns_uri_parse(AF_UNSPEC, v, &dns)) { g_set_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid DNS server address '%s'", v); return NULL; - } else if (af == AF_INET) { + } + + if (dns.addr_family == AF_INET) { if (!nm_setting_ip_config_add_dns(s_ip4, v)) PARSE_WARNING("duplicate DNS server %s", tag); } else { @@ -2606,9 +2607,8 @@ make_ip6_setting(shvarFile *ifcfg, shvarFile *network_ifcfg, gboolean routes_rea * Pick up just IPv6 addresses (IPv4 addresses are taken by make_ip4_setting()) */ for (i = 1; i < 10000; i++) { - int af; - NMIPAddr ip; - char tag[256]; + NMDnsServer dns; + char tag[256]; numbered_tag(tag, "DNS", i); nm_clear_g_free(&value); @@ -2616,7 +2616,7 @@ make_ip6_setting(shvarFile *ifcfg, shvarFile *network_ifcfg, gboolean routes_rea if (!v) break; - if (!nm_utils_dnsname_parse(AF_UNSPEC, v, &af, &ip, NULL)) { + if (!nm_dns_uri_parse(AF_UNSPEC, v, &dns)) { if (is_disabled) continue; g_set_error(error, @@ -2625,7 +2625,8 @@ make_ip6_setting(shvarFile *ifcfg, shvarFile *network_ifcfg, gboolean routes_rea "Invalid DNS server address '%s'", v); return NULL; - } else if (af == AF_INET6) { + } + if (dns.addr_family == AF_INET6) { if (is_disabled) { PARSE_WARNING("ignore DNS server addresses with method disabled/ignore"); break; diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index 21f31d8b..6e0411c6 100644 --- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -1454,6 +1454,15 @@ write_ethtool_setting(NMConnection *connection, shvarFile *ifcfg, GError **error return FALSE; } } + if (ethtool_id == NM_ETHTOOL_ID_FEC_MODE) { + if (nm_setting_option_get_uint32(NM_SETTING(s_ethtool), + nm_ethtool_data[ethtool_id]->optname, + &u32)) { + nm_sprintf_buf(prop_name, "ethtool.%s", nm_ethtool_data[ethtool_id]->optname); + set_error_unsupported(error, connection, prop_name, FALSE); + return FALSE; + } + } if (!any_option) { /* Write an empty dummy "-A" option without arguments. This is to @@ -3588,13 +3597,24 @@ do_write_construct(NMConnection *connection, } else route_ignore = FALSE; - if ((s_ip4 = nm_connection_get_setting_ip4_config(connection)) - && nm_setting_ip_config_get_dhcp_dscp(s_ip4)) { - set_error_unsupported(error, - connection, - NM_SETTING_IP4_CONFIG_SETTING_NAME "." NM_SETTING_IP_CONFIG_DHCP_DSCP, - FALSE); - return FALSE; + if ((s_ip4 = nm_connection_get_setting_ip4_config(connection))) { + if (nm_setting_ip_config_get_dhcp_dscp(s_ip4)) { + set_error_unsupported(error, + connection, + NM_SETTING_IP4_CONFIG_SETTING_NAME + "." NM_SETTING_IP_CONFIG_DHCP_DSCP, + FALSE); + return FALSE; + } + if (nm_setting_ip4_config_get_dhcp_ipv6_only_preferred(NM_SETTING_IP4_CONFIG(s_ip4)) + != NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_DEFAULT) { + set_error_unsupported(error, + connection, + NM_SETTING_IP4_CONFIG_SETTING_NAME + "." NM_SETTING_IP4_CONFIG_DHCP_IPV6_ONLY_PREFERRED, + FALSE); + return FALSE; + } } write_ip4_setting(connection, diff --git a/src/core/settings/plugins/ifcfg-rh/shvar.c b/src/core/settings/plugins/ifcfg-rh/shvar.c index 1ca2ea60..565e20f7 100644 --- a/src/core/settings/plugins/ifcfg-rh/shvar.c +++ b/src/core/settings/plugins/ifcfg-rh/shvar.c @@ -722,7 +722,7 @@ svFile_new(const char *name, int fd, const char *content) nm_assert(fd >= -1); s = g_slice_new(shvarFile); - *s = (shvarFile){ + *s = (shvarFile) { .fileName = g_strdup(name), .fd = fd, .lst_head = C_LIST_INIT(s->lst_head), @@ -796,7 +796,7 @@ line_new_parse(const char *value, gsize len) nm_assert(value); line = g_slice_new(shvarLine); - *line = (shvarLine){ + *line = (shvarLine) { .lst = C_LIST_INIT(line->lst), .dirty = TRUE, }; @@ -836,7 +836,7 @@ line_new_build(const char *key, const char *value) value = svEscape(value, &value_escaped); line = g_slice_new(shvarLine); - new_key = g_strdup(key), *line = (shvarLine){ + new_key = g_strdup(key), *line = (shvarLine) { .lst = C_LIST_INIT(line->lst), .line = value_escaped ?: g_strdup(value), .key_with_prefix = new_key, diff --git a/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 334662c3..ea978a98 100644 --- a/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -3623,7 +3623,8 @@ test_roundtrip_ethtool(void) optname = nm_ethtool_data[ethtool_id]->optname; vtype = nm_ethtool_id_get_variant_type(ethtool_id); - if (nm_ethtool_optname_is_channels(optname) || nm_ethtool_optname_is_eee(optname)) { + if (nm_ethtool_optname_is_channels(optname) || nm_ethtool_optname_is_eee(optname) + || nm_ethtool_optname_is_fec(optname)) { /* Not supported */ continue; } @@ -9520,18 +9521,24 @@ do_svUnescape_combine_ansi(GString *str_val, static void test_svUnescape(void) { -#define V0(v_value, v_expected) \ - { \ - .val = "" v_value "", .exp = v_expected, .can_concat = FALSE, \ +#define V0(v_value, v_expected) \ + { \ + .val = "" v_value "", \ + .exp = v_expected, \ + .can_concat = FALSE, \ } -#define V1(v_value, v_expected) \ - { \ - .val = "" v_value "", .exp = v_expected, .can_concat = !!v_expected, \ +#define V1(v_value, v_expected) \ + { \ + .val = "" v_value "", \ + .exp = v_expected, \ + .can_concat = !!v_expected, \ } -#define V2(v_value, v_expected) \ - { \ - .val = "" v_value "", .exp = v_expected, .can_concat = TRUE, \ - .needs_ascii_separator = TRUE, \ +#define V2(v_value, v_expected) \ + { \ + .val = "" v_value "", \ + .exp = v_expected, \ + .can_concat = TRUE, \ + .needs_ascii_separator = TRUE, \ } const UnescapeTestData data_full[] = { V1("", ""), diff --git a/src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c b/src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c index 14c82c55..1b03ce2a 100644 --- a/src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c +++ b/src/core/settings/plugins/ifupdown/nms-ifupdown-plugin.c @@ -330,7 +330,7 @@ load_eni_ifaces(NMSIfupdownPlugin *self) storage = nm_settings_storage_new(NM_SETTINGS_PLUGIN(self), uuid, NULL); sd = g_slice_new(StorageData); - *sd = (StorageData){ + *sd = (StorageData) { .connection = g_steal_pointer(&connection), .storage = g_steal_pointer(&storage), }; diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Duplicate_Gateways b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Duplicate_Gateways new file mode 100644 index 00000000..0b081761 --- /dev/null +++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Duplicate_Gateways @@ -0,0 +1,17 @@ +[connection] +id=Test Duplicate Gateways +uuid=5e2a7b1e-e4c8-4964-88c4-ca7255471aa1 +type=802-3-ethernet +autoconnect=true +timestamp=6654332 + +[ipv4] +method=manual +address1=192.168.0.5/24;192.168.0.254 +address2=192.0.2.1/16 +gateway=192.168.0.253 + +[ipv6] +method=manual +gateway=fd01::bbbb +address1=fd01::1/64;fd01::aaaa diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Bluetooth_DUN b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Bluetooth_DUN new file mode 100644 index 00000000..80de393e --- /dev/null +++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Bluetooth_DUN @@ -0,0 +1,24 @@ +[connection] +id=T-Mobile Funkadelic +uuid=76c59c25-c27c-57a4-8357-1409491cea45 +type=bluetooth +autoconnect=false +timestamp=305415219 + +[gsm] +apn=internet2.voicestream.com +password=parliament +username=george.clinton + +[bluetooth] +bdaddr=AA:B9:A1:74:55:44 +type=dun + +[ipv4] +method=auto + +[ipv6] +addr-gen-mode=default +method=auto + +[proxy] diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Bridge_Component b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Bridge_Component new file mode 100644 index 00000000..81e1ba80 --- /dev/null +++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Bridge_Component @@ -0,0 +1,14 @@ +[connection] +id=Test Write Bridge Component +uuid=7c4e34eb-419f-531c-b6ca-486f51a08d1d +type=ethernet +controller=br0 +port-type=bridge + +[ethernet] +mac-address=99:88:77:66:55:44 +mtu=1300 + +[bridge-port] +path-cost=99 +priority=3 diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Bridge_Main b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Bridge_Main new file mode 100644 index 00000000..03182b43 --- /dev/null +++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Bridge_Main @@ -0,0 +1,20 @@ +[connection] +id=Test Write Bridge Main +uuid=b23c15e0-815b-5e6e-a5f9-aea49237aa35 +type=bridge +interface-name=br0 + +[ethernet] + +[bridge] + +[ipv4] +address1=1.2.3.4/24 +gateway=1.1.1.1 +method=manual + +[ipv6] +addr-gen-mode=default +method=auto + +[proxy] diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Enum b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Enum new file mode 100644 index 00000000..3ebd6657 --- /dev/null +++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Enum @@ -0,0 +1,16 @@ +[connection] +id=Test Write Enum Property +uuid=7e4cb57c-33ff-51fc-ae49-4ee414ef0b63 +type=ethernet + +[ethernet] + +[ipv4] +method=auto + +[ipv6] +addr-gen-mode=default +ip6-privacy=2 +method=auto + +[proxy] diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Flags b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Flags new file mode 100644 index 00000000..403a3fd2 --- /dev/null +++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Flags @@ -0,0 +1,18 @@ +[connection] +id=Test Write Flags Property +uuid=19febe12-db48-5661-94cc-16529548d772 +type=gsm + +[gsm] +apn=myapn +password-flags=6 +username=adfasdfasdf + +[ipv4] +method=auto + +[ipv6] +addr-gen-mode=default +method=auto + +[proxy] diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_GSM b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_GSM new file mode 100644 index 00000000..2f6dc26c --- /dev/null +++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_GSM @@ -0,0 +1,26 @@ +[connection] +id=T-Mobile Funkadelic 2 +uuid=952d369e-52c7-5686-ad8c-37ca7e47f8b2 +type=gsm +autoconnect=false +timestamp=305415219 + +[gsm] +apn=internet2.voicestream.com +device-id=da812de91eec16620b06cd0ca5cbc7ea25245222 +home-only=true +network-id=254098 +password=parliament2 +pin=123456 +sim-id=89148000000060671234 +sim-operator-id=310260 +username=george.clinton.again + +[ipv4] +method=auto + +[ipv6] +addr-gen-mode=default +method=auto + +[proxy] diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Infiniband b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Infiniband new file mode 100644 index 00000000..f72b669e --- /dev/null +++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Infiniband @@ -0,0 +1,19 @@ +[connection] +id=Work InfiniBand +uuid=c27325f5-9eff-517a-9d96-d7897785fa5b +type=infiniband +autoconnect=false + +[infiniband] +mac-address=99:88:77:66:55:44:AB:BC:CD:DE:EF:F0:0A:1B:2C:3D:4E:5F:6F:BA +mtu=900 +transport-mode=datagram + +[ipv4] +method=auto + +[ipv6] +addr-gen-mode=default +method=auto + +[proxy] diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_TC b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_TC new file mode 100644 index 00000000..496e7bd9 --- /dev/null +++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_TC @@ -0,0 +1,21 @@ +[connection] +id=Test TC +uuid=ed1cb963-ff64-5129-99ca-e05ab3195ce4 +type=ethernet + +[ethernet] + +[ipv4] +method=auto + +[ipv6] +addr-gen-mode=default +method=auto + +[proxy] + +[tc] +qdisc.root=handle 1234: fq_codel +qdisc.ffff:fff1=ingress +tfilter.1234:=matchall action drop +tfilter.ffff:=matchall action simple sdata Hello diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Wired b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Wired new file mode 100644 index 00000000..69ca9a6d --- /dev/null +++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Wired @@ -0,0 +1,36 @@ +[connection] +id=Work Wired +uuid=9342d47a-1bab-5709-9869-c840b2eac501 +type=ethernet +autoconnect=false +timestamp=305419896 + +[ethernet] +mac-address=99:88:77:66:55:44 +mtu=900 + +[ipv4] +address1=192.168.0.5/24 +address2=1.2.3.4/8 +dns=4.2.2.1;4.2.2.2; +gateway=192.168.0.1 +method=manual +route1=10.10.10.2/24,10.10.10.1,3 +route2=1.1.1.1/8,1.2.1.1,1 +route3=2.2.2.2/7 +route4=3.3.3.3/6,0.0.0.0,4 +route4_options=cwnd=10,mtu=1492,src=1.2.3.4,weight=5 + +[ipv6] +addr-gen-mode=default +address1=abcd::beef/64 +address2=dcba::beef/56 +dns=1::cafe;2::cafe; +dns-search=wallaceandgromit.com; +method=manual +route1=1:2:3:4:5:6:7:8/64,8:7:6:5:4:3:2:1,3 +route2=2001::1000/56,2001::1111,1 +route3=4:5:6:7:8:9:0:1/63,::,5 +route4=5:6:7:8:9:0:1:2/62 + +[proxy] diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Wired_IP6 b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Wired_IP6 new file mode 100644 index 00000000..cc379ec6 --- /dev/null +++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Wired_IP6 @@ -0,0 +1,20 @@ +[connection] +id=Work Wired IP6 +uuid=0bef2d09-50a3-56b9-912a-5dc941284e3e +type=ethernet +autoconnect=false + +[ethernet] + +[ipv4] +method=disabled + +[ipv6] +addr-gen-mode=default +address1=abcd::beef/64 +dns=1::cafe; +dns-search=wallaceandgromit.com; +gateway=dcba::beef +method=manual + +[proxy] diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Wireless b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Wireless new file mode 100644 index 00000000..2fc15098 --- /dev/null +++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Write_Wireless @@ -0,0 +1,20 @@ +[connection] +id=Work Wireless +uuid=e9b337d3-6aa0-552a-822c-4b71c8ddec2e +type=wifi +autoconnect=false +timestamp=305415219 + +[wifi] +bssid=AA:B9:A1:74:55:44 +mtu=1000 +ssid=1337 + +[ipv4] +method=auto + +[ipv6] +addr-gen-mode=default +method=auto + +[proxy] diff --git a/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c b/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c index f999105a..6b6913c5 100644 --- a/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c +++ b/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c @@ -163,13 +163,48 @@ write_test_connection(NMConnection *connection, char **testfile) } static void -write_test_connection_and_reread(NMConnection *connection, gboolean normalize_connection) +write_test_connection_and_reread(NMConnection *connection, + gboolean normalize_connection, + const char *reference) { gs_free char *testfile = NULL; g_assert(NM_IS_CONNECTION(connection)); write_test_connection(connection, &testfile); + + if (reference) { + gs_free char *data1 = NULL; + gs_free char *data2 = NULL; + gsize len1; + gsize len2; + gs_free_error GError *error = NULL; + gboolean success; + + success = g_file_get_contents(testfile, &data1, &len1, &error); + nmtst_assert_success(success, error); + + if (nm_streq0(g_getenv("NM_TEST_REGENERATE"), "1")) { + success = g_file_set_contents(reference, data1, len1, &error); + nmtst_assert_success(success, error); + } else { + success = g_file_get_contents(reference, &data2, &len2, &error); + nmtst_assert_success(success, error); + + if (len1 != len2 || !nm_streq0(data1, data2)) { + g_error("The content of \"%s\" (%zu) differs from \"%s\" (%zu). Set " + "NM_TEST_REGENERATE=1 to update the files " + "in place\n\n>>>%s<<<\n\n>>>%s<<<\n", + testfile, + len1, + reference, + len2, + data1, + data2); + } + } + } + assert_reread_and_unlink(connection, normalize_connection, testfile); } @@ -369,6 +404,34 @@ test_read_valid_wired_connection(void) } static void +test_read_duplicate_gateways(void) +{ + gs_unref_object NMConnection *connection = NULL; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; + + NMTST_EXPECT_NM_WARN( + "*ipv4* ignoring gateway * from \"address*\" keys because the \"gateway\" key is set*"); + NMTST_EXPECT_NM_WARN( + "*ipv6* ignoring gateway * from \"address*\" keys because the \"gateway\" key is set*"); + connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Duplicate_Gateways"); + g_test_assert_expected_messages(); + + s_ip4 = nm_connection_get_setting_ip4_config(connection); + g_assert(s_ip4); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 2); + check_ip_address(s_ip4, 0, "192.168.0.5", 24); + check_ip_address(s_ip4, 1, "192.0.2.1", 16); + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "192.168.0.253"); + + s_ip6 = nm_connection_get_setting_ip6_config(connection); + g_assert(s_ip6); + g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip6), ==, 1); + check_ip_address(s_ip6, 0, "fd01::1", 64); + g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip6), ==, "fd01::bbbb"); +} + +static void add_one_ip_address(NMSettingIPConfig *s_ip, const char *addr, guint32 prefix) { NMIPAddress *ip_addr; @@ -408,13 +471,13 @@ add_one_ip_route(NMSettingIPConfig *s_ip, static void test_write_wired_connection(void) { - NMTST_UUID_INIT(uuid); gs_unref_object NMConnection *connection = NULL; NMSettingConnection *s_con; NMSettingWired *s_wired; NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; NMIPRoute *rt; + const char *uuid = "9342d47a-1bab-5709-9869-c840b2eac501"; const char *mac = "99:88:77:66:55:44"; const char *dns1 = "4.2.2.1"; const char *dns2 = "4.2.2.2"; @@ -529,7 +592,7 @@ test_write_wired_connection(void) /* DNS searches */ nm_setting_ip_config_add_dns_search(s_ip6, "wallaceandgromit.com"); - write_test_connection_and_reread(connection, FALSE); + write_test_connection_and_reread(connection, FALSE, TEST_KEYFILES_DIR "/Test_Write_Wired"); } static void @@ -573,12 +636,12 @@ test_read_ip6_wired_connection(void) static void test_write_ip6_wired_connection(void) { - NMTST_UUID_INIT(uuid); gs_unref_object NMConnection *connection = NULL; NMSettingConnection *s_con; NMSettingWired *s_wired; NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; + const char *uuid = "0bef2d09-50a3-56b9-912a-5dc941284e3e"; const char *dns = "1::cafe"; const char *address = "abcd::beef"; const char *gw = "dcba::beef"; @@ -634,7 +697,7 @@ test_write_ip6_wired_connection(void) /* DNS searches */ nm_setting_ip_config_add_dns_search(s_ip6, "wallaceandgromit.com"); - write_test_connection_and_reread(connection, FALSE); + write_test_connection_and_reread(connection, FALSE, TEST_KEYFILES_DIR "/Test_Write_Wired_IP6"); } static void @@ -746,12 +809,12 @@ test_read_valid_wireless_connection(void) static void test_write_wireless_connection(void) { - NMTST_UUID_INIT(uuid); gs_unref_object NMConnection *connection = NULL; NMSettingConnection *s_con; NMSettingWireless *s_wireless; NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; + const char *uuid = "e9b337d3-6aa0-552a-822c-4b71c8ddec2e"; const char *bssid = "aa:b9:a1:74:55:44"; GBytes *ssid; unsigned char tmpssid[] = {0x31, 0x33, 0x33, 0x37}; @@ -809,7 +872,7 @@ test_write_wireless_connection(void) g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); - write_test_connection_and_reread(connection, FALSE); + write_test_connection_and_reread(connection, FALSE, TEST_KEYFILES_DIR "/Test_Write_Wireless"); } static void @@ -1181,12 +1244,12 @@ test_read_bt_dun_connection(void) static void test_write_bt_dun_connection(void) { - NMTST_UUID_INIT(uuid); gs_unref_object NMConnection *connection = NULL; NMSettingConnection *s_con; NMSettingBluetooth *s_bt; NMSettingIPConfig *s_ip4; NMSettingGsm *s_gsm; + const char *uuid = "76c59c25-c27c-57a4-8357-1409491cea45"; const char *bdaddr = "aa:b9:a1:74:55:44"; guint64 timestamp = 0x12344433L; @@ -1242,7 +1305,9 @@ test_write_bt_dun_connection(void) "parliament", NULL); - write_test_connection_and_reread(connection, TRUE); + write_test_connection_and_reread(connection, + TRUE, + TEST_KEYFILES_DIR "/Test_Write_Bluetooth_DUN"); } static void @@ -1286,12 +1351,12 @@ test_read_gsm_connection(void) static void test_write_gsm_connection(void) { - NMTST_UUID_INIT(uuid); gs_unref_object NMConnection *connection = NULL; NMSettingConnection *s_con; NMSettingIPConfig *s_ip4; NMSettingGsm *s_gsm; guint64 timestamp = 0x12344433L; + const char *uuid = "952d369e-52c7-5686-ad8c-37ca7e47f8b2"; connection = nm_simple_connection_new(); @@ -1345,7 +1410,7 @@ test_write_gsm_connection(void) "310260", NULL); - write_test_connection_and_reread(connection, TRUE); + write_test_connection_and_reread(connection, TRUE, TEST_KEYFILES_DIR "/Test_Write_GSM"); } static void @@ -1830,12 +1895,12 @@ test_read_infiniband_connection(void) static void test_write_infiniband_connection(void) { - NMTST_UUID_INIT(uuid); gs_unref_object NMConnection *connection = NULL; NMSettingConnection *s_con; NMSettingInfiniband *s_ib; NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; + const char *uuid = "c27325f5-9eff-517a-9d96-d7897785fa5b"; const char *mac = "99:88:77:66:55:44:ab:bc:cd:de:ef:f0:0a:1b:2c:3d:4e:5f:6f:ba"; connection = nm_simple_connection_new(); @@ -1883,7 +1948,7 @@ test_write_infiniband_connection(void) nm_connection_add_setting(connection, NM_SETTING(s_ip6)); g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); - write_test_connection_and_reread(connection, FALSE); + write_test_connection_and_reread(connection, FALSE, TEST_KEYFILES_DIR "/Test_Write_Infiniband"); } static void @@ -1922,13 +1987,13 @@ test_read_bridge_main(void) static void test_write_bridge_main(void) { - NMTST_UUID_INIT(uuid); gs_unref_object NMConnection *connection = NULL; NMSettingConnection *s_con; NMSettingBridge *s_bridge; NMSettingWired *s_wired; NMSettingIPConfig *s_ip4; NMSettingIPConfig *s_ip6; + const char *uuid = "b23c15e0-815b-5e6e-a5f9-aea49237aa35"; connection = nm_simple_connection_new(); g_assert(connection); @@ -1982,7 +2047,9 @@ test_write_bridge_main(void) nm_connection_add_setting(connection, NM_SETTING(s_ip6)); g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); - write_test_connection_and_reread(connection, FALSE); + write_test_connection_and_reread(connection, + FALSE, + TEST_KEYFILES_DIR "/Test_Write_Bridge_Main"); } static void @@ -2022,12 +2089,12 @@ test_read_bridge_component(void) static void test_write_bridge_component(void) { - NMTST_UUID_INIT(uuid); gs_unref_object NMConnection *connection = NULL; NMSettingConnection *s_con; NMSettingBridgePort *s_port; NMSettingWired *s_wired; - const char *mac = "99:88:77:66:55:44"; + const char *mac = "99:88:77:66:55:44"; + const char *uuid = "7c4e34eb-419f-531c-b6ca-486f51a08d1d"; connection = nm_simple_connection_new(); g_assert(connection); @@ -2071,7 +2138,9 @@ test_write_bridge_component(void) 99, NULL); - write_test_connection_and_reread(connection, FALSE); + write_test_connection_and_reread(connection, + FALSE, + TEST_KEYFILES_DIR "/Test_Write_Bridge_Component"); } static void @@ -2423,11 +2492,11 @@ test_read_enum_property(void) static void test_write_enum_property(void) { - NMTST_UUID_INIT(uuid); gs_unref_object NMConnection *connection = NULL; NMSettingConnection *s_con; NMSettingWired *s_wired; NMSettingIPConfig *s_ip6; + const char *uuid = "7e4cb57c-33ff-51fc-ae49-4ee414ef0b63"; connection = nm_simple_connection_new(); @@ -2461,7 +2530,7 @@ test_write_enum_property(void) nmtst_connection_normalize(connection); - write_test_connection_and_reread(connection, FALSE); + write_test_connection_and_reread(connection, FALSE, TEST_KEYFILES_DIR "/Test_Write_Enum"); } static void @@ -2482,10 +2551,10 @@ test_read_flags_property(void) static void test_write_flags_property(void) { - NMTST_UUID_INIT(uuid); gs_unref_object NMConnection *connection = NULL; NMSettingConnection *s_con; NMSetting *s_gsm; + const char *uuid = "19febe12-db48-5661-94cc-16529548d772"; connection = nm_simple_connection_new(); @@ -2517,7 +2586,7 @@ test_write_flags_property(void) nmtst_connection_normalize(connection); - write_test_connection_and_reread(connection, FALSE); + write_test_connection_and_reread(connection, FALSE, TEST_KEYFILES_DIR "/Test_Write_Flags"); } /*****************************************************************************/ @@ -2586,9 +2655,11 @@ test_write_tc_config(void) NMTCAction *action; GError *error = NULL; - connection = - nmtst_create_minimal_connection("Test TC", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); - s_tc = nm_setting_tc_config_new(); + connection = nmtst_create_minimal_connection("Test TC", + "ed1cb963-ff64-5129-99ca-e05ab3195ce4", + NM_SETTING_WIRED_SETTING_NAME, + NULL); + s_tc = nm_setting_tc_config_new(); qdisc1 = nm_tc_qdisc_new("fq_codel", TC_H_ROOT, &error); nmtst_assert_success(qdisc1, error); @@ -2622,7 +2693,7 @@ test_write_tc_config(void) nm_connection_add_setting(connection, s_tc); nmtst_connection_normalize(connection); - write_test_connection_and_reread(connection, FALSE); + write_test_connection_and_reread(connection, FALSE, TEST_KEYFILES_DIR "/Test_Write_TC"); nm_tc_qdisc_unref(qdisc1); nm_tc_qdisc_unref(qdisc2); @@ -2856,6 +2927,8 @@ main(int argc, char **argv) g_test_add_func("/keyfile/test_read_valid_wired_connection", test_read_valid_wired_connection); g_test_add_func("/keyfile/test_write_wired_connection", test_write_wired_connection); + g_test_add_func("/keyfile/test_read_duplicate_gateways", test_read_duplicate_gateways); + g_test_add_func("/keyfile/test_read_ip6_wired_connection", test_read_ip6_wired_connection); g_test_add_func("/keyfile/test_write_ip6_wired_connection", test_write_ip6_wired_connection); diff --git a/src/core/supplicant/nm-supplicant-config.c b/src/core/supplicant/nm-supplicant-config.c index 4433e809..9e066395 100644 --- a/src/core/supplicant/nm-supplicant-config.c +++ b/src/core/supplicant/nm-supplicant-config.c @@ -154,7 +154,7 @@ nm_supplicant_config_add_option_with_type(NMSupplicantConfig *self, } opt = g_slice_new(ConfigOption); - *opt = (ConfigOption){ + *opt = (ConfigOption) { .value = nm_memdup_nul(value, len), .len = len, .type = type, diff --git a/src/core/supplicant/nm-supplicant-interface.c b/src/core/supplicant/nm-supplicant-interface.c index eb7a40a5..d5f56dcd 100644 --- a/src/core/supplicant/nm-supplicant-interface.c +++ b/src/core/supplicant/nm-supplicant-interface.c @@ -714,7 +714,7 @@ _bss_info_properties_changed(NMSupplicantInterface *self, if (v_v) { arr_data = g_variant_get_fixed_array(v_v, &arr_len, 1); if (arr_len == ETH_ALEN && memcmp(arr_data, &nm_ether_addr_zero, ETH_ALEN) != 0 - && memcmp(arr_data, (char[ETH_ALEN]){0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, ETH_ALEN) + && memcmp(arr_data, (char[ETH_ALEN]) {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, ETH_ALEN) != 0) { /* pass */ } else @@ -839,7 +839,7 @@ _bss_info_add(NMSupplicantInterface *self, const char *object_path) } bss_info = g_slice_new(NMSupplicantBssInfo); - *bss_info = (NMSupplicantBssInfo){ + *bss_info = (NMSupplicantBssInfo) { ._self = self, .bss_path = g_steal_pointer(&bss_path), ._init_cancellable = g_cancellable_new(), @@ -953,7 +953,7 @@ _peer_info_properties_changed(NMSupplicantInterface *self, if (v_v) { arr_data = g_variant_get_fixed_array(v_v, &arr_len, 1); if (arr_len == ETH_ALEN && memcmp(arr_data, &nm_ether_addr_zero, ETH_ALEN) != 0 - && memcmp(arr_data, (char[ETH_ALEN]){0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, ETH_ALEN) + && memcmp(arr_data, (char[ETH_ALEN]) {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, ETH_ALEN) != 0) { /* pass */ } else @@ -1037,7 +1037,7 @@ _peer_info_add(NMSupplicantInterface *self, const char *object_path) } peer_info = g_slice_new(NMSupplicantPeerInfo); - *peer_info = (NMSupplicantPeerInfo){ + *peer_info = (NMSupplicantPeerInfo) { ._self = self, .peer_path = g_steal_pointer(&peer_path), ._init_cancellable = g_cancellable_new(), @@ -1831,7 +1831,7 @@ _wps_start(NMSupplicantInterface *self, const char *type, const char *bssid, con } wps_data = g_slice_new(WpsData); - *wps_data = (WpsData){ + *wps_data = (WpsData) { .self = self, .type = g_strdup(type), .bssid = g_strdup(bssid), @@ -2381,7 +2381,7 @@ add_network(NMSupplicantInterface *self) * For that we also have a shutdown_wait_obj so that on exit we still wait * to handle the response. */ add_network_data = g_slice_new(AddNetworkData); - *add_network_data = (AddNetworkData){ + *add_network_data = (AddNetworkData) { .assoc_data = priv->assoc_data, .name_owner = nm_ref_string_ref(priv->name_owner), .object_path = nm_ref_string_ref(priv->object_path), @@ -2534,7 +2534,7 @@ nm_supplicant_interface_assoc(NMSupplicantInterface *self, nm_supplicant_interface_disconnect(self); assoc_data = g_slice_new(AssocData); - *assoc_data = (AssocData){ + *assoc_data = (AssocData) { .self = self, .cfg = g_object_ref(cfg), .callback = callback, @@ -2707,7 +2707,7 @@ nm_supplicant_interface_request_scan(NMSupplicantInterface *se } data = g_slice_new(ScanRequestData); - *data = (ScanRequestData){ + *data = (ScanRequestData) { .self = self, .callback = callback, .user_data = user_data, diff --git a/src/core/supplicant/nm-supplicant-manager.c b/src/core/supplicant/nm-supplicant-manager.c index 3b805693..ea8d0865 100644 --- a/src/core/supplicant/nm-supplicant-manager.c +++ b/src/core/supplicant/nm-supplicant-manager.c @@ -693,7 +693,7 @@ nm_supplicant_manager_create_interface(NMSupplicantManager *self priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE(self); handle = g_slice_new(NMSupplMgrCreateIfaceHandle); - *handle = (NMSupplMgrCreateIfaceHandle){ + *handle = (NMSupplMgrCreateIfaceHandle) { .self = g_object_ref(self), .callback = callback, .callback_user_data = user_data, diff --git a/src/core/tests/config/test-config.c b/src/core/tests/config/test-config.c index 8365fc82..2980cda7 100644 --- a/src/core/tests/config/test-config.c +++ b/src/core/tests/config/test-config.c @@ -965,7 +965,8 @@ _set_values_user_atomic_section_1_set(NMConfig *config, g_key_file_set_string(keyfile, "atomic-prefix-1.section-b", "key1", "user-value1"); g_key_file_set_string(keyfile, "non-atomic-prefix-1.section-a", "nap1-key1", "user-value1"); g_key_file_set_string(keyfile, "non-atomic-prefix-1.section-a", "nap1-key2", "user-value2"); - *out_expected_changes = NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER; + *out_expected_changes = + NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER | NM_CONFIG_CHANGE_CONFIG_FILES; } static void @@ -976,7 +977,9 @@ _set_values_user_atomic_section_1_check(NMConfig *config, NMConfigData *old_data) { if (is_change_event) - g_assert(changes == (NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER)); + g_assert(changes + == (NM_CONFIG_CHANGE_VALUES | NM_CONFIG_CHANGE_VALUES_USER + | NM_CONFIG_CHANGE_CONFIG_FILES)); assert_config_value(config_data, "atomic-prefix-1.section-a", "key1", "user-value1"); assert_config_value(config_data, "atomic-prefix-1.section-a", "key2", "user-value2"); assert_config_value(config_data, "atomic-prefix-1.section-b", "key1", "user-value1"); diff --git a/src/core/tests/test-core.c b/src/core/tests/test-core.c index 71a3d878..2ff41f00 100644 --- a/src/core/tests/test-core.c +++ b/src/core/tests/test-core.c @@ -1027,7 +1027,7 @@ test_connection_match_ip6_routes(void) } #define do_test_wildcard_match_eval(str, ...) \ - nm_wildcard_match_check(str, (const char *const[]){__VA_ARGS__}, NM_NARG(__VA_ARGS__)) + nm_wildcard_match_check(str, (const char *const[]) {__VA_ARGS__}, NM_NARG(__VA_ARGS__)) #define do_test_wildcard_match(str, result, ...) \ g_assert(do_test_wildcard_match_eval(str, __VA_ARGS__) == result) @@ -1244,7 +1244,7 @@ _test_match_spec_device(const GSList *specs, const char *match_str) { if (match_str && g_str_has_prefix(match_str, MATCH_S390)) return nm_match_spec_device(specs, - &((const NMMatchSpecDeviceData){ + &((const NMMatchSpecDeviceData) { .s390_subchannels = &match_str[NM_STRLEN(MATCH_S390)], })); if (match_str && g_str_has_prefix(match_str, MATCH_DRIVER)) { @@ -1257,13 +1257,13 @@ _test_match_spec_device(const GSList *specs, const char *match_str) t++; } return nm_match_spec_device(specs, - &((const NMMatchSpecDeviceData){ + &((const NMMatchSpecDeviceData) { .driver = s, .driver_version = t, })); } return nm_match_spec_device(specs, - &((const NMMatchSpecDeviceData){ + &((const NMMatchSpecDeviceData) { .interface_name = match_str, })); } @@ -1789,28 +1789,28 @@ test_nm_utils_strbuf_append(void) } \ G_STMT_END -#define _strbuf_append_c(buf, len, ch) \ - G_STMT_START \ - { \ - char **_buf = (buf); \ - gsize *_len = (len); \ - char _ch = (ch); \ - \ - switch (nmtst_get_rand_uint32() % 4) { \ - case 0: \ - nm_strbuf_append(_buf, _len, "%c", _ch); \ - break; \ - case 1: \ - nm_strbuf_append_str(_buf, _len, ((char[2]){_ch, 0})); \ - break; \ - case 2: \ - nm_strbuf_append_bin(_buf, _len, &_ch, 1); \ - break; \ - case 3: \ - nm_strbuf_append_c(_buf, _len, _ch); \ - break; \ - } \ - } \ +#define _strbuf_append_c(buf, len, ch) \ + G_STMT_START \ + { \ + char **_buf = (buf); \ + gsize *_len = (len); \ + char _ch = (ch); \ + \ + switch (nmtst_get_rand_uint32() % 4) { \ + case 0: \ + nm_strbuf_append(_buf, _len, "%c", _ch); \ + break; \ + case 1: \ + nm_strbuf_append_str(_buf, _len, ((char[2]) {_ch, 0})); \ + break; \ + case 2: \ + nm_strbuf_append_bin(_buf, _len, &_ch, 1); \ + break; \ + case 3: \ + nm_strbuf_append_c(_buf, _len, _ch); \ + break; \ + } \ + } \ G_STMT_END for (buf_len = 0; buf_len < 10; buf_len++) { diff --git a/src/core/tests/test-l3cfg.c b/src/core/tests/test-l3cfg.c index 6b82fe43..6e11ca51 100644 --- a/src/core/tests/test-l3cfg.c +++ b/src/core/tests/test-l3cfg.c @@ -111,7 +111,7 @@ _test_fixture_1_teardown(TestFixture1 *f) g_object_unref(f->platform); nm_dedup_multi_index_unref(f->multiidx); - *f = (TestFixture1){ + *f = (TestFixture1) { .test_idx = 0, }; } @@ -192,11 +192,13 @@ _test_l3cfg_signal_notify(NML3Cfg *l3cfg, nm_assert(NM_IS_L3_CONFIG_DATA(ti->l3cd)); nm_assert(ti->tag); } - } else if (notify_data->notify_type == NM_L3_CONFIG_NOTIFY_TYPE_L3CD_CHANGED) { - g_assert(!notify_data->l3cd_changed.l3cd_old - || NM_IS_L3_CONFIG_DATA(notify_data->l3cd_changed.l3cd_old)); - g_assert(!notify_data->l3cd_changed.l3cd_new - || NM_IS_L3_CONFIG_DATA(notify_data->l3cd_changed.l3cd_new)); + } else if (NM_IN_SET(notify_data->notify_type, + NM_L3_CONFIG_NOTIFY_TYPE_PRE_COMMIT, + NM_L3_CONFIG_NOTIFY_TYPE_POST_COMMIT)) { + g_assert(!notify_data->commit.l3cd_old + || NM_IS_L3_CONFIG_DATA(notify_data->commit.l3cd_old)); + g_assert(!notify_data->commit.l3cd_new + || NM_IS_L3_CONFIG_DATA(notify_data->commit.l3cd_new)); return; } diff --git a/src/core/vpn/nm-vpn-connection.c b/src/core/vpn/nm-vpn-connection.c index c14682b8..d0607160 100644 --- a/src/core/vpn/nm-vpn-connection.c +++ b/src/core/vpn/nm-vpn-connection.c @@ -1206,6 +1206,7 @@ _parent_device_l3cd_add_gateway_route(NML3ConfigData *l3cd, r = nm_platform_ip_route_get(platform, addr_family, vpn_gw, + 0, ifindex, (NMPObject **) &route_resolved); if (r >= 0) { @@ -1238,7 +1239,7 @@ _parent_device_l3cd_add_gateway_route(NML3ConfigData *l3cd, return FALSE; if (IS_IPv4) { - route.r4 = (NMPlatformIP4Route){ + route.r4 = (NMPlatformIP4Route) { .ifindex = ifindex, .network = vpn_gw->addr4, .plen = 32, @@ -1248,7 +1249,7 @@ _parent_device_l3cd_add_gateway_route(NML3ConfigData *l3cd, .table_any = TRUE, }; } else { - route.r6 = (NMPlatformIP6Route){ + route.r6 = (NMPlatformIP6Route) { .ifindex = ifindex, .network = vpn_gw->addr6, .plen = 128, @@ -1267,7 +1268,7 @@ _parent_device_l3cd_add_gateway_route(NML3ConfigData *l3cd, * the parent device's gateway would get routed through the VPN and fail. */ if (IS_IPv4) { - route.r4 = (NMPlatformIP4Route){ + route.r4 = (NMPlatformIP4Route) { .network = parent_gw.addr4, .plen = 32, .rt_source = NM_IP_CONFIG_SOURCE_VPN, @@ -1275,7 +1276,7 @@ _parent_device_l3cd_add_gateway_route(NML3ConfigData *l3cd, .table_any = TRUE, }; } else { - route.r6 = (NMPlatformIP6Route){ + route.r6 = (NMPlatformIP6Route) { .network = parent_gw.addr6, .plen = 128, .rt_source = NM_IP_CONFIG_SOURCE_VPN, @@ -2006,11 +2007,11 @@ _dbus_signal_ip_config_cb(NMVpnConnection *self, int addr_family, GVariant *dict &priv->ip_data_x[IS_IPv4].gw_internal); if (IS_IPv4) { - address.a4 = (NMPlatformIP4Address){ + address.a4 = (NMPlatformIP4Address) { .plen = 24, }; } else { - address.a6 = (NMPlatformIP6Address){ + address.a6 = (NMPlatformIP6Address) { .plen = 128, }; } @@ -2059,14 +2060,14 @@ _dbus_signal_ip_config_cb(NMVpnConnection *self, int addr_family, GVariant *dict if (IS_IPv4) { if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP4_CONFIG_DNS, "au", &var_iter)) { while (g_variant_iter_next(var_iter, "u", &u32)) - nm_l3_config_data_add_nameserver_detail(l3cd, addr_family, &u32, NULL); + nm_l3_config_data_add_nameserver_addr(l3cd, addr_family, &u32); g_variant_iter_free(var_iter); } } else { if (g_variant_lookup(dict, NM_VPN_PLUGIN_IP6_CONFIG_DNS, "aay", &var_iter)) { while (g_variant_iter_next(var_iter, "@ay", &v)) { if (nm_ip_addr_set_from_variant(AF_INET6, &v_addr, v, NULL)) - nm_l3_config_data_add_nameserver_detail(l3cd, addr_family, &v_addr, NULL); + nm_l3_config_data_add_nameserver_addr(l3cd, addr_family, &v_addr); g_variant_unref(v); } g_variant_iter_free(var_iter); @@ -2212,7 +2213,7 @@ _dbus_signal_ip_config_cb(NMVpnConnection *self, int addr_family, GVariant *dict if (prefix > 128) continue; - route.r6 = (NMPlatformIP6Route){ + route.r6 = (NMPlatformIP6Route) { .plen = prefix, .table_any = TRUE, .metric_any = TRUE, @@ -2258,7 +2259,7 @@ _dbus_signal_ip_config_cb(NMVpnConnection *self, int addr_family, GVariant *dict NMPlatformIPXRoute route; if (IS_IPv4) { - route.r4 = (NMPlatformIP4Route){ + route.r4 = (NMPlatformIP4Route) { .ifindex = ip_ifindex, .rt_source = NM_IP_CONFIG_SOURCE_VPN, .gateway = priv->ip_data_4.gw_internal.addr4, @@ -2267,7 +2268,7 @@ _dbus_signal_ip_config_cb(NMVpnConnection *self, int addr_family, GVariant *dict .mss = mss, }; } else { - route.r6 = (NMPlatformIP6Route){ + route.r6 = (NMPlatformIP6Route) { .ifindex = ip_ifindex, .rt_source = NM_IP_CONFIG_SOURCE_VPN, .gateway = priv->ip_data_6.gw_internal.addr6, diff --git a/src/libnm-base/nm-base.h b/src/libnm-base/nm-base.h index 4b1bff54..048c0241 100644 --- a/src/libnm-base/nm-base.h +++ b/src/libnm-base/nm-base.h @@ -135,7 +135,11 @@ typedef enum { NM_ETHTOOL_ID_CHANNELS_COMBINED, _NM_ETHTOOL_ID_CHANNELS_LAST = NM_ETHTOOL_ID_CHANNELS_COMBINED, - _NM_ETHTOOL_ID_LAST = _NM_ETHTOOL_ID_CHANNELS_LAST, + _NM_ETHTOOL_ID_FEC_FIRST = _NM_ETHTOOL_ID_CHANNELS_LAST + 1, + NM_ETHTOOL_ID_FEC_MODE = _NM_ETHTOOL_ID_FEC_FIRST, + _NM_ETHTOOL_ID_FEC_LAST = NM_ETHTOOL_ID_FEC_MODE, + + _NM_ETHTOOL_ID_LAST = _NM_ETHTOOL_ID_FEC_LAST, _NM_ETHTOOL_ID_COALESCE_NUM = (_NM_ETHTOOL_ID_COALESCE_LAST - _NM_ETHTOOL_ID_COALESCE_FIRST + 1), @@ -158,6 +162,7 @@ typedef enum { NM_ETHTOOL_TYPE_PAUSE, NM_ETHTOOL_TYPE_CHANNELS, NM_ETHTOOL_TYPE_EEE, + NM_ETHTOOL_TYPE_FEC, } NMEthtoolType; /****************************************************************************/ @@ -198,6 +203,12 @@ nm_ethtool_id_is_eee(NMEthtoolID id) return id >= _NM_ETHTOOL_ID_EEE_FIRST && id <= _NM_ETHTOOL_ID_EEE_LAST; } +static inline gboolean +nm_ethtool_id_is_fec(NMEthtoolID id) +{ + return id >= _NM_ETHTOOL_ID_FEC_FIRST && id <= _NM_ETHTOOL_ID_FEC_LAST; +} + /*****************************************************************************/ typedef enum { diff --git a/src/libnm-base/nm-config-base.h b/src/libnm-base/nm-config-base.h index 362a183c..d101c95c 100644 --- a/src/libnm-base/nm-config-base.h +++ b/src/libnm-base/nm-config-base.h @@ -55,8 +55,10 @@ #define NM_CONFIG_KEYFILE_KEY_IFUPDOWN_MANAGED "managed" -#define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_SEARCHES "searches" -#define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_OPTIONS "options" +#define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_SEARCHES "searches" +#define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_OPTIONS "options" +#define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_CERTIFICATION_AUTHORITY "certification-authority" +#define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_RESOLVE_MODE "resolve-mode" #define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_DOMAIN_SERVERS "servers" #define NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_DOMAIN_OPTIONS "options" diff --git a/src/libnm-base/nm-ethtool-base.c b/src/libnm-base/nm-ethtool-base.c index a02b9018..6f2ab211 100644 --- a/src/libnm-base/nm-ethtool-base.c +++ b/src/libnm-base/nm-ethtool-base.c @@ -11,10 +11,10 @@ /*****************************************************************************/ -#define ETHT_DATA(xname) \ - [NM_ETHTOOL_ID_##xname] = (&((const NMEthtoolData){ \ - .optname = NM_ETHTOOL_OPTNAME_##xname, \ - .id = NM_ETHTOOL_ID_##xname, \ +#define ETHT_DATA(xname) \ + [NM_ETHTOOL_ID_##xname] = (&((const NMEthtoolData) { \ + .optname = NM_ETHTOOL_OPTNAME_##xname, \ + .id = NM_ETHTOOL_ID_##xname, \ })) const NMEthtoolData *const nm_ethtool_data[_NM_ETHTOOL_ID_NUM + 1] = { @@ -111,6 +111,7 @@ const NMEthtoolData *const nm_ethtool_data[_NM_ETHTOOL_ID_NUM + 1] = { ETHT_DATA(CHANNELS_TX), ETHT_DATA(CHANNELS_OTHER), ETHT_DATA(CHANNELS_COMBINED), + ETHT_DATA(FEC_MODE), [_NM_ETHTOOL_ID_NUM] = NULL, }; @@ -201,6 +202,7 @@ static const guint8 _by_name[_NM_ETHTOOL_ID_NUM] = { NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION, NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, NM_ETHTOOL_ID_FEATURE_TXVLAN, + NM_ETHTOOL_ID_FEC_MODE, NM_ETHTOOL_ID_PAUSE_AUTONEG, NM_ETHTOOL_ID_PAUSE_RX, NM_ETHTOOL_ID_PAUSE_TX, @@ -305,6 +307,8 @@ nm_ethtool_id_to_type(NMEthtoolID id) return NM_ETHTOOL_TYPE_CHANNELS; if (nm_ethtool_id_is_eee(id)) return NM_ETHTOOL_TYPE_EEE; + if (nm_ethtool_id_is_fec(id)) + return NM_ETHTOOL_TYPE_FEC; return NM_ETHTOOL_TYPE_UNKNOWN; } @@ -319,6 +323,7 @@ nm_ethtool_id_get_variant_type(NMEthtoolID ethtool_id) return G_VARIANT_TYPE_BOOLEAN; case NM_ETHTOOL_TYPE_CHANNELS: case NM_ETHTOOL_TYPE_COALESCE: + case NM_ETHTOOL_TYPE_FEC: case NM_ETHTOOL_TYPE_RING: return G_VARIANT_TYPE_UINT32; case NM_ETHTOOL_TYPE_UNKNOWN: diff --git a/src/libnm-base/nm-ethtool-utils-base.h b/src/libnm-base/nm-ethtool-utils-base.h index 75fb63c5..435e88d2 100644 --- a/src/libnm-base/nm-ethtool-utils-base.h +++ b/src/libnm-base/nm-ethtool-utils-base.h @@ -109,6 +109,8 @@ G_BEGIN_DECLS #define NM_ETHTOOL_OPTNAME_CHANNELS_OTHER "channels-other" #define NM_ETHTOOL_OPTNAME_CHANNELS_COMBINED "channels-combined" +#define NM_ETHTOOL_OPTNAME_FEC_MODE "fec-mode" + #define NM_ETHTOOL_OPTNAME_EEE_ENABLED "eee-enabled" /*****************************************************************************/ diff --git a/src/libnm-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver index 23e6042f..faa872d7 100644 --- a/src/libnm-client-impl/libnm.ver +++ b/src/libnm-client-impl/libnm.ver @@ -2007,4 +2007,44 @@ libnm_1_50_0 { global: nm_setting_wireless_channel_width_get_type; nm_setting_wireless_get_channel_width; -} libnm_1_48_0; \ No newline at end of file +} libnm_1_48_0; + +libnm_1_52_0 { +global: + nm_device_ipvlan_get_mode; + nm_device_ipvlan_get_parent; + nm_device_ipvlan_get_private; + nm_device_ipvlan_get_type; + nm_device_ipvlan_get_vepa; + nm_setting_ip4_config_get_dhcp_ipv6_only_preferred; + nm_setting_ip4_dhcp_ipv6_only_preferred_get_type; + nm_setting_ip_config_get_routed_dns; + nm_setting_ip_config_get_shared_dhcp_range; + nm_setting_ip_config_get_shared_dhcp_lease_time; + nm_setting_ip_config_routed_dns_get_type; + nm_setting_ipvlan_get_mode; + nm_setting_ipvlan_get_parent; + nm_setting_gsm_get_initial_eps_password; + nm_setting_gsm_get_initial_eps_username; + nm_setting_gsm_get_initial_eps_noauth; + nm_setting_gsm_get_initial_eps_refuse_pap; + nm_setting_gsm_get_initial_eps_refuse_chap; + nm_setting_gsm_get_initial_eps_refuse_eap; + nm_setting_gsm_get_initial_eps_refuse_mschap; + nm_setting_gsm_get_initial_eps_refuse_mschapv2; + nm_setting_ipvlan_get_private; + nm_setting_ipvlan_get_type; + nm_setting_ipvlan_get_vepa; + nm_setting_ipvlan_mode_get_type; + nm_setting_ipvlan_new; + nm_setting_ip_config_get_dhcp_send_hostname_v2; + nm_setting_connection_get_ip_ping_address; + nm_setting_connection_get_ip_ping_timeout; + nm_setting_connection_add_ip_ping_address; + nm_setting_connection_remove_ip_ping_address; + nm_setting_connection_clear_ip_ping_addresses; + nm_setting_connection_remove_ip_ping_address_by_value; + nm_setting_connection_get_ip_ping_addresses_require_all; + nm_setting_ethtool_fec_mode_get_type; + nm_ethtool_optname_is_fec; +} libnm_1_50_0; diff --git a/src/libnm-client-impl/meson.build b/src/libnm-client-impl/meson.build index 3dd2338a..e50e8fbd 100644 --- a/src/libnm-client-impl/meson.build +++ b/src/libnm-client-impl/meson.build @@ -20,6 +20,7 @@ libnm_client_impl_sources = files( 'nm-device-hsr.c', 'nm-device-infiniband.c', 'nm-device-ip-tunnel.c', + 'nm-device-ipvlan.c', 'nm-device-loopback.c', 'nm-device-macsec.c', 'nm-device-macvlan.c', diff --git a/src/libnm-client-impl/nm-active-connection.c b/src/libnm-client-impl/nm-active-connection.c index 0d186361..9008256a 100644 --- a/src/libnm-client-impl/nm-active-connection.c +++ b/src/libnm-client-impl/nm-active-connection.c @@ -624,7 +624,7 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_connection_active = NML_DBUS_META PROP_CONTROLLER, "o", active_connection_update_prop_controller, - .extra.property_vtable_o = &((const NMLDBusPropertVTableO){ + .extra.property_vtable_o = &((const NMLDBusPropertVTableO) { .get_o_type_fcn = (nm_device_get_type)})), NML_DBUS_META_PROPERTY_INIT_B("Default", PROP_DEFAULT, @@ -664,7 +664,7 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_connection_active = NML_DBUS_META PROP_MASTER, "o", active_connection_update_prop_controller, - .extra.property_vtable_o = &((const NMLDBusPropertVTableO){ + .extra.property_vtable_o = &((const NMLDBusPropertVTableO) { .get_o_type_fcn = (nm_device_get_type)})), NML_DBUS_META_PROPERTY_INIT_O("SpecificObject", PROP_SPECIFIC_OBJECT_PATH, diff --git a/src/libnm-client-impl/nm-client.c b/src/libnm-client-impl/nm-client.c index 6e722c5c..fc30cd06 100644 --- a/src/libnm-client-impl/nm-client.c +++ b/src/libnm-client-impl/nm-client.c @@ -32,6 +32,7 @@ #include "nm-device-hsr.h" #include "nm-device-infiniband.h" #include "nm-device-ip-tunnel.h" +#include "nm-device-ipvlan.h" #include "nm-device-loopback.h" #include "nm-device-macsec.h" #include "nm-device-macvlan.h" @@ -418,7 +419,7 @@ nml_init_data_new_sync(GCancellable *cancellable, GMainLoop *main_loop, GError * NMLInitData *init_data; init_data = g_slice_new(NMLInitData); - *init_data = (NMLInitData){ + *init_data = (NMLInitData) { .cancellable = nm_g_object_ref(cancellable), .is_sync = TRUE, .data.sync = @@ -436,7 +437,7 @@ nml_init_data_new_async(GCancellable *cancellable, GTask *task_take) NMLInitData *init_data; init_data = g_slice_new(NMLInitData); - *init_data = (NMLInitData){ + *init_data = (NMLInitData) { .cancellable = nm_g_object_ref(cancellable), .is_sync = FALSE, .data.async = @@ -1102,7 +1103,7 @@ nml_dbus_object_new(NMRefString *dbus_path_take) nm_assert(NM_IS_REF_STRING(dbus_path_take)); dbobj = g_slice_new(NMLDBusObject); - *dbobj = (NMLDBusObject){ + *dbobj = (NMLDBusObject) { .dbus_path = g_steal_pointer(&dbus_path_take), .ref_count = 1, .dbus_objects_lst = C_LIST_INIT(dbobj->dbus_objects_lst), @@ -1208,7 +1209,7 @@ nml_dbus_object_iface_data_get(NMLDBusObject *dbobj, G_STRUCT_OFFSET(NMLDBusObjIfaceData, prop_datas) + (meta_iface ? (sizeof(NMLDBusObjPropData) * meta_iface->n_dbus_properties) : 0u)); if (meta_iface) { - *db_iface_data = (NMLDBusObjIfaceData){ + *db_iface_data = (NMLDBusObjIfaceData) { .dbus_iface.meta = meta_iface, .dbus_iface_is_wellknown = TRUE, .changed_prop_lst_head = C_LIST_INIT(db_iface_data->changed_prop_lst_head), @@ -1216,7 +1217,7 @@ nml_dbus_object_iface_data_get(NMLDBusObject *dbobj, }; db_prop_data = &db_iface_data->prop_datas[0]; for (i = 0; i < meta_iface->n_dbus_properties; i++, db_prop_data++) { - *db_prop_data = (NMLDBusObjPropData){ + *db_prop_data = (NMLDBusObjPropData) { .prop_data_value = NULL, .changed_prop_lst = C_LIST_INIT(db_prop_data->changed_prop_lst), }; @@ -3911,7 +3912,7 @@ _request_wait_start(GTask *task_take, } request_data = g_slice_new(RequestWaitData); - *request_data = (RequestWaitData){ + *request_data = (RequestWaitData) { .task = g_steal_pointer(&task), .op_name = op_name, .gtype = gtype, @@ -7076,7 +7077,7 @@ _init_release_all(NMClient *self) nm_assert(c_list_is_empty(&priv->obj_changed_lst_head)); - dbus_objects_lst_heads = ((CList *[]){ + dbus_objects_lst_heads = ((CList *[]) { &priv->dbus_objects_lst_head_on_dbus, &priv->dbus_objects_lst_head_with_nmobj_not_ready, &priv->dbus_objects_lst_head_with_nmobj_ready, @@ -9148,7 +9149,7 @@ nm_client_wait_shutdown(NMClient *client, } data = g_slice_new(WaitShutdownData); - *data = (WaitShutdownData){ + *data = (WaitShutdownData) { .cancellable = nm_g_object_ref(cancellable), .task = g_object_ref(task), .result = -1, diff --git a/src/libnm-client-impl/nm-device-ipvlan.c b/src/libnm-client-impl/nm-device-ipvlan.c new file mode 100644 index 00000000..85d799c2 --- /dev/null +++ b/src/libnm-client-impl/nm-device-ipvlan.c @@ -0,0 +1,233 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-ipvlan.h" + +#include "nm-setting-connection.h" +#include "nm-setting-ipvlan.h" +#include "nm-utils.h" +#include "nm-object-private.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PARENT, PROP_MODE, PROP_PRIVATE, PROP_VEPA, ); + +typedef struct { + NMLDBusPropertyO parent; + char *mode; + bool private_flag; + bool vepa; +} NMDeviceIpvlanPrivate; + +struct _NMDeviceIpvlan { + NMDevice parent; + NMDeviceIpvlanPrivate _priv; +}; + +struct _NMDeviceIpvlanClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceIpvlan, nm_device_ipvlan, NM_TYPE_DEVICE) + +#define NM_DEVICE_IPVLAN_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceIpvlan, NM_IS_DEVICE_IPVLAN, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_ipvlan_get_parent: + * @device: a #NMDeviceIpvlan + * + * Returns: (transfer none): the device's parent device + * + * Since: 1.52 + **/ +NMDevice * +nm_device_ipvlan_get_parent(NMDeviceIpvlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_IPVLAN(device), FALSE); + + return nml_dbus_property_o_get_obj(&NM_DEVICE_IPVLAN_GET_PRIVATE(device)->parent); +} + +/** + * nm_device_ipvlan_get_mode: + * @device: a #NMDeviceIpvlan + * + * Gets the IPVLAN mode of the device. + * + * Returns: the IPVLAN mode. This is the internal string used by the + * device, and must not be modified. + * + * Since: 1.52 + **/ +const char * +nm_device_ipvlan_get_mode(NMDeviceIpvlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_IPVLAN(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_IPVLAN_GET_PRIVATE(device)->mode); +} + +/** + * nm_device_ipvlan_get_private + * @device: a #NMDeviceIpvlan + * + * Gets the private flag of the device. + * + * Returns: the private flag of the device. + * + * Since: 1.52 + **/ +gboolean +nm_device_ipvlan_get_private(NMDeviceIpvlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_IPVLAN(device), FALSE); + + return NM_DEVICE_IPVLAN_GET_PRIVATE(device)->private_flag; +} + +/** + * nm_device_ipvlan_get_vepa + * @device: a #NMDeviceIpvlan + * + * Gets the VEPA flag of the device. + * + * Returns: the VEPA flag of the device. + * + * Since: 1.52 + **/ +gboolean +nm_device_ipvlan_get_vepa(NMDeviceIpvlan *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_IPVLAN(device), FALSE); + + return NM_DEVICE_IPVLAN_GET_PRIVATE(device)->vepa; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceIpvlan *device = NM_DEVICE_IPVLAN(object); + + switch (prop_id) { + case PROP_PARENT: + g_value_set_object(value, nm_device_ipvlan_get_parent(device)); + break; + case PROP_MODE: + g_value_set_string(value, nm_device_ipvlan_get_mode(device)); + break; + case PROP_PRIVATE: + g_value_set_boolean(value, nm_device_ipvlan_get_private(device)); + break; + case PROP_VEPA: + g_value_set_boolean(value, nm_device_ipvlan_get_vepa(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +nm_device_ipvlan_init(NMDeviceIpvlan *device) +{} + +static void +finalize(GObject *object) +{ + NMDeviceIpvlanPrivate *priv = NM_DEVICE_IPVLAN_GET_PRIVATE(object); + + g_free(priv->mode); + + G_OBJECT_CLASS(nm_device_ipvlan_parent_class)->finalize(object); +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ipvlan = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_IPVLAN, + nm_device_ipvlan_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_S("Mode", PROP_MODE, NMDeviceIpvlan, _priv.mode), + NML_DBUS_META_PROPERTY_INIT_O_PROP("Parent", + PROP_PARENT, + NMDeviceIpvlan, + _priv.parent, + nm_device_get_type), + NML_DBUS_META_PROPERTY_INIT_B("Private", PROP_PRIVATE, NMDeviceIpvlan, _priv.private_flag), + NML_DBUS_META_PROPERTY_INIT_B("Vepa", PROP_VEPA, NMDeviceIpvlan, _priv.vepa), ), ); + +static void +nm_device_ipvlan_class_init(NMDeviceIpvlanClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceIpvlan); + + _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1(nm_object_class, NMDeviceIpvlanPrivate, parent); + + /** + * NMDeviceIpvlan:parent: + * + * The devices's parent device. + * + * Since: 1.52 + **/ + obj_properties[PROP_PARENT] = g_param_spec_object(NM_DEVICE_IPVLAN_PARENT, + "", + "", + NM_TYPE_DEVICE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceIpvlan:mode: + * + * The IPVLAN mode. + * + * Since: 1.52 + **/ + obj_properties[PROP_MODE] = g_param_spec_string(NM_DEVICE_IPVLAN_MODE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceIpvlan:private: + * + * Whether the device has the private flag. + * + * Since: 1.52 + **/ + obj_properties[PROP_PRIVATE] = g_param_spec_boolean(NM_DEVICE_IPVLAN_PRIVATE, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceIpvlan:vepa: + * + * Whether the device has the VEPA flag. + * + * Since: 1.52 + **/ + obj_properties[PROP_VEPA] = g_param_spec_boolean(NM_DEVICE_IPVLAN_VEPA, + "", + "", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_ipvlan); +} diff --git a/src/libnm-client-impl/nm-device.c b/src/libnm-client-impl/nm-device.c index dc868f5b..f9d7329b 100644 --- a/src/libnm-client-impl/nm-device.c +++ b/src/libnm-client-impl/nm-device.c @@ -314,6 +314,7 @@ coerce_type(NMDeviceType type) case NM_DEVICE_TYPE_VRF: case NM_DEVICE_TYPE_LOOPBACK: case NM_DEVICE_TYPE_HSR: + case NM_DEVICE_TYPE_IPVLAN: return type; } return NM_DEVICE_TYPE_UNKNOWN; @@ -609,7 +610,7 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device = NML_DBUS_META_IFACE_INIT .prop_struct_offset = G_STRUCT_OFFSET(NMDevicePrivate, property_ao[PROPERTY_AO_IDX_PORTS]), .extra.property_vtable_ao = - &((const NMLDBusPropertVTableAO){.get_o_type_fcn = (nm_device_get_type)})), + &((const NMLDBusPropertVTableAO) {.get_o_type_fcn = (nm_device_get_type)})), NML_DBUS_META_PROPERTY_INIT_B("Real", PROP_REAL, NMDevicePrivate, real), NML_DBUS_META_PROPERTY_INIT_IGNORE("State", "u"), NML_DBUS_META_PROPERTY_INIT_FCN("StateReason", @@ -1817,6 +1818,8 @@ get_type_name(NMDevice *device) return _("Loopback"); case NM_DEVICE_TYPE_HSR: return _("HSR"); + case NM_DEVICE_TYPE_IPVLAN: + return _("IPVLAN"); case NM_DEVICE_TYPE_GENERIC: case NM_DEVICE_TYPE_UNUSED1: case NM_DEVICE_TYPE_UNUSED2: @@ -3001,7 +3004,7 @@ nm_lldp_neighbor_new(void) NMLldpNeighbor *neigh; neigh = g_slice_new(NMLldpNeighbor); - *neigh = (NMLldpNeighbor){ + *neigh = (NMLldpNeighbor) { .refcount = 1, .attrs = g_hash_table_new_full(nm_str_hash, g_str_equal, diff --git a/src/libnm-client-impl/nm-ip-config.c b/src/libnm-client-impl/nm-ip-config.c index c054f2cc..ad5f08f8 100644 --- a/src/libnm-client-impl/nm-ip-config.c +++ b/src/libnm-client-impl/nm-ip-config.c @@ -166,25 +166,32 @@ _notify_update_prop_nameservers(NMClient *client, g_variant_iter_init(&iter, value); while (g_variant_iter_next(&iter, "a{sv}", &iter_v)) { - const char *key; - GVariant *val; + const char *key; + GVariant *val; + gs_free char *nameserver = NULL; while (g_variant_iter_next(iter_v, "{&sv}", &key, &val)) { - if (nm_streq(key, "address")) { + if (nm_streq(key, "address") && !nameserver) { gs_free char *val_str = NULL; if (!g_variant_is_of_type(val, G_VARIANT_TYPE_STRING)) goto next; if (!nm_inet_parse_str(AF_INET, g_variant_get_string(val, NULL), &val_str)) goto next; - if (!arr) - arr = g_ptr_array_new(); - g_ptr_array_add(arr, g_steal_pointer(&val_str)); - goto next; + nameserver = g_steal_pointer(&val_str); + } else if (nm_streq(key, "uri")) { + nameserver = g_variant_dup_string(val, NULL); } next: g_variant_unref(val); } + + if (nameserver) { + if (!arr) + arr = g_ptr_array_new(); + g_ptr_array_add(arr, g_steal_pointer(&nameserver)); + } + g_variant_iter_free(iter_v); } if (arr && arr->len > 0) diff --git a/src/libnm-client-impl/nm-libnm-utils.c b/src/libnm-client-impl/nm-libnm-utils.c index 8af234ce..1b25c92c 100644 --- a/src/libnm-client-impl/nm-libnm-utils.c +++ b/src/libnm-client-impl/nm-libnm-utils.c @@ -785,6 +785,7 @@ const NMLDBusMetaIface *const _nml_dbus_meta_ifaces[] = { &_nml_dbus_meta_iface_nm_device_hsr, &_nml_dbus_meta_iface_nm_device_iptunnel, &_nml_dbus_meta_iface_nm_device_infiniband, + &_nml_dbus_meta_iface_nm_device_ipvlan, &_nml_dbus_meta_iface_nm_device_loopback, &_nml_dbus_meta_iface_nm_device_lowpan, &_nml_dbus_meta_iface_nm_device_macsec, diff --git a/src/libnm-client-impl/nm-libnm-utils.h b/src/libnm-client-impl/nm-libnm-utils.h index 61ff442d..7dcf8c18 100644 --- a/src/libnm-client-impl/nm-libnm-utils.h +++ b/src/libnm-client-impl/nm-libnm-utils.h @@ -440,8 +440,8 @@ typedef struct { v_obj_properties_idx, \ .prop_struct_offset = \ NM_STRUCT_OFFSET_ENSURE_TYPE(NMLDBusPropertyO, v_container, v_field), \ - .extra.property_vtable_o = \ - &((const NMLDBusPropertVTableO){.get_o_type_fcn = (v_get_o_type_fcn), ##__VA_ARGS__})) + .extra.property_vtable_o = &( \ + (const NMLDBusPropertVTableO) {.get_o_type_fcn = (v_get_o_type_fcn), ##__VA_ARGS__})) #define NML_DBUS_META_PROPERTY_INIT_AO_PROP(v_dbus_property_name, \ v_obj_properties_idx, \ @@ -456,7 +456,7 @@ typedef struct { .prop_struct_offset = \ NM_STRUCT_OFFSET_ENSURE_TYPE(NMLDBusPropertyAO, v_container, v_field), \ .extra.property_vtable_ao = &( \ - (const NMLDBusPropertVTableAO){.get_o_type_fcn = (v_get_o_type_fcn), ##__VA_ARGS__})) + (const NMLDBusPropertVTableAO) {.get_o_type_fcn = (v_get_o_type_fcn), ##__VA_ARGS__})) #define NML_DBUS_META_PROPERTY_INIT_FCN(v_dbus_property_name, \ v_obj_properties_idx, \ @@ -559,12 +559,12 @@ struct _NMLDBusMetaIface { #define NML_DBUS_META_IFACE_OBJ_PROPERTIES() \ .obj_properties = (const GParamSpec *const *) (obj_properties), \ .n_obj_properties = _PROPERTY_ENUMS_LAST, \ - .obj_properties_reverse_idx = ((guint8[_PROPERTY_ENUMS_LAST]){}) + .obj_properties_reverse_idx = ((guint8[_PROPERTY_ENUMS_LAST]) {}) -#define NML_DBUS_META_IFACE_DBUS_PROPERTIES(...) \ - .dbus_properties = ((const NMLDBusMetaProperty[]){__VA_ARGS__}), \ - .n_dbus_properties = \ - (sizeof((const NMLDBusMetaProperty[]){__VA_ARGS__}) / sizeof(NMLDBusMetaProperty)) +#define NML_DBUS_META_IFACE_DBUS_PROPERTIES(...) \ + .dbus_properties = ((const NMLDBusMetaProperty[]) {__VA_ARGS__}), \ + .n_dbus_properties = \ + (sizeof((const NMLDBusMetaProperty[]) {__VA_ARGS__}) / sizeof(NMLDBusMetaProperty)) #define NML_DBUS_META_IFACE_INIT(v_dbus_iface_name, v_get_type_fcn, v_interface_prio, ...) \ {.dbus_iface_name = "" v_dbus_iface_name "", \ @@ -579,7 +579,7 @@ struct _NMLDBusMetaIface { NML_DBUS_META_IFACE_OBJ_PROPERTIES(), \ ##__VA_ARGS__) -extern const NMLDBusMetaIface *const _nml_dbus_meta_ifaces[46]; +extern const NMLDBusMetaIface *const _nml_dbus_meta_ifaces[47]; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_accesspoint; @@ -596,6 +596,7 @@ extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_generic; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_hsr; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_infiniband; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_iptunnel; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ipvlan; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_loopback; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_lowpan; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_macsec; @@ -639,7 +640,7 @@ void _nml_dbus_meta_class_init_with_properties_impl(GObjectClass #define _nml_dbus_meta_class_init_with_properties(object_class, ...) \ _nml_dbus_meta_class_init_with_properties_impl( \ (object_class), \ - ((const NMLDBusMetaIface *const[]){__VA_ARGS__, NULL})) + ((const NMLDBusMetaIface *const[]) {__VA_ARGS__, NULL})) /*****************************************************************************/ @@ -792,7 +793,7 @@ struct _NMObjectClass { * variable here. */ \ nm_assert(!_f.klass); \ \ - _f = (_NMObjectClassFieldInfo){ \ + _f = (_NMObjectClassFieldInfo) { \ .parent = _klass->field_name, \ .klass = _klass, \ .offset = (_offset), \ diff --git a/src/libnm-client-impl/nm-secret-agent-old.c b/src/libnm-client-impl/nm-secret-agent-old.c index 8f7e0b4d..73850bf1 100644 --- a/src/libnm-client-impl/nm-secret-agent-old.c +++ b/src/libnm-client-impl/nm-secret-agent-old.c @@ -476,7 +476,7 @@ impl_get_secrets(NMSecretAgentOld *self, GVariant *parameters, GDBusMethodInvoca _cancel_get_secret_request(self, info, "Request aborted due to new request"); info = g_slice_new(GetSecretsInfo); - *info = (GetSecretsInfo){ + *info = (GetSecretsInfo) { .context = context, .connection_path = g_strdup(arg_connection_path), .setting_name = g_strdup(arg_setting_name), diff --git a/src/libnm-client-impl/nm-vpn-service-plugin.c b/src/libnm-client-impl/nm-vpn-service-plugin.c index d26a4ff5..1235a2a5 100644 --- a/src/libnm-client-impl/nm-vpn-service-plugin.c +++ b/src/libnm-client-impl/nm-vpn-service-plugin.c @@ -232,11 +232,30 @@ nm_vpn_service_plugin_disconnect(NMVpnServicePlugin *plugin, GError **err) } static void -nm_vpn_service_plugin_emit_quit(NMVpnServicePlugin *plugin) +flushed_cb(GObject *object, GAsyncResult *res, gpointer data) { + NMVpnServicePlugin *plugin = NM_VPN_SERVICE_PLUGIN(data); + GError *error = NULL; + + if (!g_dbus_connection_flush_finish(G_DBUS_CONNECTION(object), res, &error)) { + g_warning("Error flushing D-Bus connection: %s", error->message); + g_error_free(error); + } + g_signal_emit(plugin, signals[QUIT], 0); } +static void +flush_and_quit(NMVpnServicePlugin *plugin) +{ + NMVpnServicePluginPrivate *priv = NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(plugin); + + if (priv->connection != NULL) + g_dbus_connection_flush(priv->connection, NULL, flushed_cb, plugin); + else + g_signal_emit(plugin, signals[QUIT], 0); +} + /** * nm_vpn_service_plugin_shutdown: * @plugin: the #NMVpnServicePlugin instance @@ -305,7 +324,8 @@ quit_timer_expired(gpointer data) NMVpnServicePlugin *self = NM_VPN_SERVICE_PLUGIN(data); NM_VPN_SERVICE_PLUGIN_GET_PRIVATE(self)->quit_timer = 0; - nm_vpn_service_plugin_emit_quit(self); + flush_and_quit(self); + return G_SOURCE_REMOVE; } @@ -997,17 +1017,17 @@ impl_vpn_service_plugin_set_failure(NMVpnServicePlugin *plugin, /*****************************************************************************/ static void -_emit_quit(gpointer data, gpointer user_data) +_flush_and_quit_plugin(gpointer data, gpointer user_data) { NMVpnServicePlugin *plugin = data; - nm_vpn_service_plugin_emit_quit(plugin); + flush_and_quit(plugin); } static void sigterm_handler(int signum) { - g_slist_foreach(active_plugins, _emit_quit, NULL); + g_slist_foreach(active_plugins, _flush_and_quit_plugin, NULL); } static void @@ -1204,7 +1224,7 @@ state_changed(NMVpnServicePlugin *plugin, NMVpnServiceState state) break; case NM_VPN_SERVICE_STATE_STOPPED: if (priv->dbus_watch_peer) - nm_vpn_service_plugin_emit_quit(plugin); + flush_and_quit(plugin); else schedule_quit_timer(plugin); nm_clear_g_dbus_connection_signal(nm_vpn_service_plugin_get_connection(plugin), diff --git a/src/libnm-client-impl/tests/test-libnm.c b/src/libnm-client-impl/tests/test-libnm.c index f6bf1567..f56521a4 100644 --- a/src/libnm-client-impl/tests/test-libnm.c +++ b/src/libnm-client-impl/tests/test-libnm.c @@ -2285,7 +2285,7 @@ typedef struct { const char *val; } ReadVpnDetailData; -#define READ_VPN_DETAIL_DATA(...) ((ReadVpnDetailData[]){__VA_ARGS__}) +#define READ_VPN_DETAIL_DATA(...) ((ReadVpnDetailData[]) {__VA_ARGS__}) static gboolean _do_read_vpn_details_impl1(const char *file, @@ -2693,6 +2693,7 @@ test_types(void) G(nm_device_hsr_get_type), G(nm_device_infiniband_get_type), G(nm_device_ip_tunnel_get_type), + G(nm_device_ipvlan_get_type), G(nm_device_macsec_get_type), G(nm_device_macvlan_get_type), G(nm_device_modem_capabilities_get_type), @@ -2771,6 +2772,8 @@ test_types(void) G(nm_setting_ip6_config_privacy_get_type), G(nm_setting_ip_config_get_type), G(nm_setting_ip_tunnel_get_type), + G(nm_setting_ipvlan_get_type), + G(nm_setting_ipvlan_mode_get_type), G(nm_setting_mac_randomization_get_type), G(nm_setting_macsec_get_type), G(nm_setting_macsec_mode_get_type), @@ -3001,8 +3004,13 @@ test_nml_dbus_meta(void) g_assert(NM_IS_OBJECT_CLASS(p->klass)); g_assert(g_type_is_a(gtype, G_TYPE_FROM_CLASS(p->klass))); if (ii == 0) + /* If there is more than one NMLDBusPropertyO needed in the struct + * associated to the DBus object, they must be all in the same struct field + * as an array. This is later used on nm-object.c to perform operations on + * all the object properties at once. */ g_assert(p->klass->property_o_info == p); else + /* Same check than above if branch but for NMLDBusPropertyAO. */ g_assert(p->klass->property_ao_info == p); g_assert_cmpint(p->klass->priv_ptr_offset, >, 0); if (p_prev) { @@ -3401,6 +3409,11 @@ test_dbus_meta_types(void) NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, }, { + NM_DBUS_INTERFACE_DEVICE_IPVLAN, + NM_TYPE_DEVICE_IPVLAN, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + }, + { NM_DBUS_INTERFACE_DEVICE_MACSEC, NM_TYPE_DEVICE_MACSEC, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, diff --git a/src/libnm-client-impl/tests/test-nm-client.c b/src/libnm-client-impl/tests/test-nm-client.c index 3d527324..39831509 100644 --- a/src/libnm-client-impl/tests/test-nm-client.c +++ b/src/libnm-client-impl/tests/test-nm-client.c @@ -1099,7 +1099,7 @@ test_connection_invalid(void) g_assert_cmpint(connections->len, ==, 3); n_found = nmtst_find_all_indexes(connections->pdata, connections->len, - (gpointer *) ((const char *[]){path0, path1, path2}), + (gpointer *) ((const char *[]) {path0, path1, path2}), 3, _test_connection_invalid_find_connections, NULL, @@ -1134,7 +1134,7 @@ test_connection_invalid(void) g_assert_cmpint(connections->len, ==, 4); n_found = nmtst_find_all_indexes(connections->pdata, connections->len, - (gpointer *) ((const char *[]){path0, path1, path2, path3}), + (gpointer *) ((const char *[]) {path0, path1, path2, path3}), 4, _test_connection_invalid_find_connections, NULL, @@ -1166,7 +1166,7 @@ test_connection_invalid(void) g_assert_cmpint(connections->len, ==, 4); n_found = nmtst_find_all_indexes(connections->pdata, connections->len, - (gpointer *) ((const char *[]){path0, path1, path2, path3}), + (gpointer *) ((const char *[]) {path0, path1, path2, path3}), 4, _test_connection_invalid_find_connections, NULL, @@ -1202,7 +1202,7 @@ test_connection_invalid(void) g_assert_cmpint(connections->len, ==, 4); n_found = nmtst_find_all_indexes(connections->pdata, connections->len, - (gpointer *) ((const char *[]){path0, path1, path2, path3}), + (gpointer *) ((const char *[]) {path0, path1, path2, path3}), 4, _test_connection_invalid_find_connections, NULL, @@ -1232,7 +1232,7 @@ test_connection_invalid(void) g_assert_cmpint(connections->len, ==, 4); n_found = nmtst_find_all_indexes(connections->pdata, connections->len, - (gpointer *) ((const char *[]){path0, path1, path2, path3}), + (gpointer *) ((const char *[]) {path0, path1, path2, path3}), 4, _test_connection_invalid_find_connections, NULL, @@ -1279,7 +1279,7 @@ test_connection_invalid(void) g_assert_cmpint(connections->len, ==, 4); n_found = nmtst_find_all_indexes(connections->pdata, connections->len, - (gpointer *) ((const char *[]){path0, path1, path2, path3}), + (gpointer *) ((const char *[]) {path0, path1, path2, path3}), 4, _test_connection_invalid_find_connections, NULL, @@ -1326,7 +1326,7 @@ test_connection_invalid(void) g_assert_cmpint(connections->len, ==, 4); n_found = nmtst_find_all_indexes(connections->pdata, connections->len, - (gpointer *) ((const char *[]){path0, path1, path2, path3}), + (gpointer *) ((const char *[]) {path0, path1, path2, path3}), 4, _test_connection_invalid_find_connections, NULL, diff --git a/src/libnm-client-impl/tests/test-secret-agent.c b/src/libnm-client-impl/tests/test-secret-agent.c index 1fffb556..9871b1a4 100644 --- a/src/libnm-client-impl/tests/test-secret-agent.c +++ b/src/libnm-client-impl/tests/test-secret-agent.c @@ -344,7 +344,7 @@ test_cleanup(TestSecretAgentData *sadata, gconstpointer test_data) g_free(sadata->ifname); g_free(sadata->con_id); - *sadata = (TestSecretAgentData){}; + *sadata = (TestSecretAgentData) {}; nmtst_context_busy_watcher_wait(&watcher_data); diff --git a/src/libnm-client-public/NetworkManager.h b/src/libnm-client-public/NetworkManager.h index 646431f6..3608168f 100644 --- a/src/libnm-client-public/NetworkManager.h +++ b/src/libnm-client-public/NetworkManager.h @@ -45,6 +45,7 @@ #include "nm-setting-ip6-config.h" #include "nm-setting-ip-config.h" #include "nm-setting-ip-tunnel.h" +#include "nm-setting-ipvlan.h" #include "nm-setting-link.h" #include "nm-setting-loopback.h" #include "nm-setting-macsec.h" @@ -115,6 +116,7 @@ #include "nm-device-hsr.h" #include "nm-device-infiniband.h" #include "nm-device-ip-tunnel.h" +#include "nm-device-ipvlan.h" #include "nm-device-loopback.h" #include "nm-device-macsec.h" #include "nm-device-macvlan.h" diff --git a/src/libnm-client-public/meson.build b/src/libnm-client-public/meson.build index dccbb11f..b8ae9cce 100644 --- a/src/libnm-client-public/meson.build +++ b/src/libnm-client-public/meson.build @@ -21,6 +21,7 @@ libnm_client_headers = files( 'nm-device-hsr.h', 'nm-device-infiniband.h', 'nm-device-ip-tunnel.h', + 'nm-device-ipvlan.h', 'nm-device-loopback.h', 'nm-device-macsec.h', 'nm-device-macvlan.h', diff --git a/src/libnm-client-public/nm-autoptr.h b/src/libnm-client-public/nm-autoptr.h index c38f270c..0f6e59c4 100644 --- a/src/libnm-client-public/nm-autoptr.h +++ b/src/libnm-client-public/nm-autoptr.h @@ -44,6 +44,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceGeneric, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceHsr, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceIPTunnel, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceInfiniband, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceIpvlan, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceLoopback, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceMacsec, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMDeviceMacvlan, g_object_unref) @@ -87,6 +88,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingIP6Config, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingIPConfig, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingIPTunnel, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingInfiniband, g_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingIpvlan, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingLink, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingLoopback, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(NMSettingMacsec, g_object_unref) diff --git a/src/libnm-client-public/nm-device-ipvlan.h b/src/libnm-client-public/nm-device-ipvlan.h new file mode 100644 index 00000000..768abc80 --- /dev/null +++ b/src/libnm-client-public/nm-device-ipvlan.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024 Red Hat, Inc. + */ + +#ifndef __NM_DEVICE_IPVLAN_H__ +#define __NM_DEVICE_IPVLAN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) +#error "Only <NetworkManager.h> can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_IPVLAN (nm_device_ipvlan_get_type()) +#define NM_DEVICE_IPVLAN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_IPVLAN, NMDeviceIpvlan)) +#define NM_DEVICE_IPVLAN_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_IPVLAN, NMDeviceIpvlanClass)) +#define NM_IS_DEVICE_IPVLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_IPVLAN)) +#define NM_IS_DEVICE_IPVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_IPVLAN)) +#define NM_DEVICE_IPVLAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_IPVLAN, NMDeviceIpvlanClass)) + +#define NM_DEVICE_IPVLAN_PARENT "parent" +#define NM_DEVICE_IPVLAN_MODE "mode" +#define NM_DEVICE_IPVLAN_PRIVATE "private" +#define NM_DEVICE_IPVLAN_VEPA "vepa" + +/** + * NMDeviceIpvlan: + * + * Since: 1.52 + */ +typedef struct _NMDeviceIpvlan NMDeviceIpvlan; +typedef struct _NMDeviceIpvlanClass NMDeviceIpvlanClass; + +NM_AVAILABLE_IN_1_52 +GType nm_device_ipvlan_get_type(void); + +NM_AVAILABLE_IN_1_52 +NMDevice *nm_device_ipvlan_get_parent(NMDeviceIpvlan *device); +NM_AVAILABLE_IN_1_52 +const char *nm_device_ipvlan_get_mode(NMDeviceIpvlan *device); +NM_AVAILABLE_IN_1_52 +gboolean nm_device_ipvlan_get_private(NMDeviceIpvlan *device); +NM_AVAILABLE_IN_1_52 +gboolean nm_device_ipvlan_get_vepa(NMDeviceIpvlan *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_IPVLAN_H__ */ diff --git a/src/libnm-client-public/nm-ethtool-utils.h b/src/libnm-client-public/nm-ethtool-utils.h index 75fb63c5..435e88d2 100644 --- a/src/libnm-client-public/nm-ethtool-utils.h +++ b/src/libnm-client-public/nm-ethtool-utils.h @@ -109,6 +109,8 @@ G_BEGIN_DECLS #define NM_ETHTOOL_OPTNAME_CHANNELS_OTHER "channels-other" #define NM_ETHTOOL_OPTNAME_CHANNELS_COMBINED "channels-combined" +#define NM_ETHTOOL_OPTNAME_FEC_MODE "fec-mode" + #define NM_ETHTOOL_OPTNAME_EEE_ENABLED "eee-enabled" /*****************************************************************************/ diff --git a/src/libnm-client-test/nm-test-utils-impl.c b/src/libnm-client-test/nm-test-utils-impl.c index ba541ad8..36d18c50 100644 --- a/src/libnm-client-test/nm-test-utils-impl.c +++ b/src/libnm-client-test/nm-test-utils-impl.c @@ -314,7 +314,7 @@ add_device_common(NMTstcServiceInfo *sinfo, loop = g_main_loop_new(nm_client_get_main_context(client), FALSE); - info = (AddDeviceInfo){ + info = (AddDeviceInfo) { .ifname = ifname, .loop = loop, }; diff --git a/src/libnm-core-aux-intern/meson.build b/src/libnm-core-aux-intern/meson.build index a58921e3..f413cde4 100644 --- a/src/libnm-core-aux-intern/meson.build +++ b/src/libnm-core-aux-intern/meson.build @@ -1,4 +1,5 @@ # SPDX-License-Identifier: LGPL-2.1-or-later +libnm_core_aux_intern_inc = include_directories('.') libnm_core_aux_intern = static_library( 'nm-core-aux-intern', diff --git a/src/libnm-core-aux-intern/nm-libnm-core-utils.c b/src/libnm-core-aux-intern/nm-libnm-core-utils.c index b38accb2..5e7b90a4 100644 --- a/src/libnm-core-aux-intern/nm-libnm-core-utils.c +++ b/src/libnm-core-aux-intern/nm-libnm-core-utils.c @@ -479,6 +479,151 @@ nm_utils_validate_dhcp_dscp(const char *dscp, GError **error) } gboolean +nm_utils_validate_shared_dhcp_range(const char *shared_dhcp_range, + GPtrArray *addresses, + GError **error) +{ + char *start_address_str; + char *end_address_str; + NMIPAddress *interface_address_with_prefix; + NMIPAddr interface_address; + NMIPAddr start_address; + NMIPAddr end_address; + guint32 i; + guint32 mask; + guint32 prefix_length; + guint32 start_network; + guint32 end_network; + guint32 interface_network; + guint32 start_ip_length; + bool range_is_in_interface_network; + gs_free char *to_free = NULL; + + g_return_val_if_fail(!error || !(*error), FALSE); + + if (!shared_dhcp_range) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("NULL DHCP range; it should be provided as <START_IP>,<END_IP>.")); + return FALSE; + } + + if (!*shared_dhcp_range) { + return TRUE; + } + + if (!addresses) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Non-NULL range and NULL addresses detected.")); + return FALSE; + } + + end_address_str = strchr(shared_dhcp_range, ','); + if (!end_address_str) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Invalid DHCP range; it should be provided as <START_IP>,<END_IP>.")); + return FALSE; + } + + start_ip_length = end_address_str - shared_dhcp_range; + if (start_ip_length > 15) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Start IP has invalid length.")); + return FALSE; + } + + start_address_str = nm_strndup_a(200, shared_dhcp_range, start_ip_length, &to_free); + ++end_address_str; /* end address is pointing to ',', shift it to the actual address */ + + if (!nm_inet_parse_bin(AF_INET, start_address_str, NULL, &start_address)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Start IP is invalid.")); + return FALSE; + } + + if (!nm_inet_parse_bin(AF_INET, end_address_str, NULL, &end_address)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("End IP is invalid.")); + return FALSE; + } + + if (ntohl(start_address.addr4) > ntohl(end_address.addr4)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Start IP should be lower than the end IP.")); + return FALSE; + } + + range_is_in_interface_network = FALSE; + for (i = 0; i < (*addresses).len; ++i) { + interface_address_with_prefix = (NMIPAddress *) addresses->pdata[i]; + nm_inet_parse_bin(AF_INET, + nm_ip_address_get_address(interface_address_with_prefix), + NULL, + &interface_address); + prefix_length = nm_ip_address_get_prefix(interface_address_with_prefix); + mask = nm_utils_ip4_prefix_to_netmask(prefix_length); + + interface_network = interface_address.addr4 & mask; + start_network = start_address.addr4 & mask; + end_network = end_address.addr4 & mask; + + if (start_network == interface_network && end_network == interface_network) { + range_is_in_interface_network = TRUE; + break; + } + } + + if (!range_is_in_interface_network) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Requested range is not in any network configured on the interface.")); + return FALSE; + } + + return TRUE; +} + +gboolean +nm_utils_validate_shared_dhcp_lease_time(int shared_dhcp_lease_time, GError **error) +{ + g_return_val_if_fail(!error || !(*error), FALSE); + + if (shared_dhcp_lease_time == 0 || shared_dhcp_lease_time == G_MAXINT32) { + return TRUE; + } + + if (shared_dhcp_lease_time < NM_MIN_FINITE_LEASE_TIME + || NM_MAX_FINITE_LEASE_TIME < shared_dhcp_lease_time) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Invalid DHCP lease time value; it should be either default or a positive " + "number between %u and %u or %s."), + NM_MIN_FINITE_LEASE_TIME, + NM_MAX_FINITE_LEASE_TIME, + NM_INFINITE_LEASE_TIME); + return FALSE; + } + + return TRUE; +} + +gboolean nm_settings_connection_validate_permission_user(const char *item, gssize len) { gsize l; @@ -555,112 +700,295 @@ nm_mptcp_flags_normalize(NMMptcpFlags flags) /*****************************************************************************/ +/* + * nm_dns_uri_parse: + * @addr_family: the address family, or AF_UNSPEC to autodetect it + * @str: the name server URI string to parse + * @dns: the name server descriptor to fill, or %NULL + * + * Parses the given name server URI string. Each name server is represented + * by the following grammar: + * + * NAMESERVER := { PLAIN | TLS_URI | UDP_URI } + * PLAIN := { ipv4address | ipv6address } [ '#' SERVERNAME ] + * TLS_URI := 'dns+tls://' URI_ADDRESS [ ':' PORT ] [ '#' SERVERNAME ] + * UDP_URI := 'dns+udp://' URI_ADDRESS [ ':' PORT ] + * URI_ADDRESS := { ipv4address | '[' ipv6address [ '%' ifname ] ']' } + * + * Examples: + * + * 192.0.2.0 + * 192.0.2.0#example.com + * 2001:db8::1 + * dns+tls://192.0.2.0 + * dns+tls://[2001:db8::1] + * dns+tls://192.0.2.0:53#example.com + * dns+udp://[fe80::1%enp1s0] + * + * Note that on return, the lifetime of the members in the @dns struct is + * the same as the input string @str. + * + * Returns: %TRUE on success, %FALSE on failure + */ gboolean -nm_utils_dnsname_parse(int addr_family, - const char *dns, - int *out_addr_family, - gpointer /* (NMIPAddr **) */ out_addr, - const char **out_servername) +nm_dns_uri_parse(int addr_family, const char *str, NMDnsServer *dns) { - gs_free char *dns_heap = NULL; - const char *s; - NMIPAddr addr; + NMDnsServer dns_stack; + gs_free char *addr_port_heap = NULL; + gs_free char *addr_heap = NULL; + const char *addr_port; + const char *addr; + const char *name; + const char *port; nm_assert_addr_family_or_unspec(addr_family); - nm_assert(!out_addr || out_addr_family || NM_IN_SET(addr_family, AF_INET, AF_INET6)); if (!dns) + dns = &dns_stack; + + if (!str) return FALSE; - s = strchr(dns, '#'); + *dns = (NMDnsServer) { + .port = -1, + }; - if (s) { - dns = nm_strndup_a(200, dns, s - dns, &dns_heap); - s++; + if (NM_STR_HAS_PREFIX(str, "dns+tls://")) { + dns->scheme = NM_DNS_URI_SCHEME_TLS; + str += NM_STRLEN("dns+tls://"); + } else if (NM_STR_HAS_PREFIX(str, "dns+udp://")) { + dns->scheme = NM_DNS_URI_SCHEME_UDP; + str += NM_STRLEN("dns+udp://"); + } else { + name = strchr(str, '#'); + if (name) { + str = nm_strndup_a(200, str, name - str, &addr_heap); + name++; + } + + if (name && name[0] == '\0') { + /* empty DoT server name is not allowed */ + return FALSE; + } + + if (!nm_inet_parse_bin(addr_family, str, &dns->addr_family, &dns->addr)) + return FALSE; + + dns->servername = name; + dns->scheme = NM_DNS_URI_SCHEME_NONE; + + return TRUE; + } + + addr_port = str; + name = strrchr(addr_port, '#'); + if (name) { + addr_port = nm_strndup_a(100, addr_port, name - addr_port, &addr_port_heap); + name++; + if (*name == '\0') { + /* empty DoT server name not allowed */ + return FALSE; + } + dns->servername = name; } - if (s && s[0] == '\0') { - /* "ADDR#" empty DoT SNI name is not allowed. */ + if (addr_family != AF_INET && *addr_port == '[') { + const char *end; + char *perc; + + addr_family = AF_INET6; + addr_port++; + end = strchr(addr_port, ']'); + if (!end) + return FALSE; + addr = nm_strndup_a(100, addr_port, end - addr_port, &addr_heap); + + /* IPv6 link-local scope-id */ + perc = strchr(addr, '%'); + if (perc) { + *perc = '\0'; + if (g_strlcpy(dns->interface, perc + 1, sizeof(dns->interface)) + >= sizeof(dns->interface)) + return FALSE; + } + + /* port */ + end++; + if (*end == ':') { + end++; + dns->port = _nm_utils_ascii_str_to_int64(end, 10, 0, 65535, G_MAXINT32); + if (dns->port == G_MAXINT32) + return FALSE; + } + } else if (addr_family != AF_INET6) { + /* square brackets are mandatory for IPv6, so it must be IPv4 */ + + addr_family = AF_INET; + addr = addr_port; + + /* port */ + port = strchr(addr_port, ':'); + if (port) { + addr = nm_strndup_a(100, addr_port, port - addr_port, &addr_heap); + port++; + dns->port = _nm_utils_ascii_str_to_int64(port, 10, 0, 65535, G_MAXINT32); + if (dns->port == G_MAXINT32) + return FALSE; + } + } else { return FALSE; } - if (!nm_inet_parse_bin(addr_family, dns, &addr_family, out_addr ? &addr : NULL)) + if (!nm_inet_parse_bin(addr_family, addr, &dns->addr_family, &dns->addr)) + return FALSE; + + if (dns->scheme != NM_DNS_URI_SCHEME_TLS && dns->servername) + return FALSE; + + /* For now, allow the interface only for IPv6 link-local addresses */ + if (dns->interface[0] + && (dns->addr_family != AF_INET6 || !IN6_IS_ADDR_LINKLOCAL(&dns->addr.addr6))) return FALSE; - NM_SET_OUT(out_addr_family, addr_family); - if (out_addr) - nm_ip_addr_set(addr_family, out_addr, &addr); - NM_SET_OUT(out_servername, s); return TRUE; } -const char * -nm_utils_dnsname_construct(int addr_family, - gconstpointer /* (const NMIPAddr *) */ addr, - const char *server_name, - char *result, - gsize result_len) +/* @nm_dns_uri_parse_plain: + * @addr_family: the address family, or AF_UNSPEC to autodetect it + * @str: the name server URI string + * @out_addrstr: the buffer to fill with the address string on return, + * or %NULL. Must be of size at least NM_INET_ADDRSTRLEN. + * @out_addr: the %NMIPAddr struct to fill on return, or %NULL + * + * Returns whether the string contains a "plain" (DNS over UDP on port 53) + * name server. In such case, it fills the arguments with the address + * of the name server. + * + * Returns: %TRUE on success, %FALSE if the string can't be parsed or + * if it's not a plain name server. + */ +gboolean +nm_dns_uri_parse_plain(int addr_family, const char *str, char *out_addrstr, NMIPAddr *out_addr) { - char sbuf[NM_INET_ADDRSTRLEN]; - gsize l; - int d; + NMDnsServer dns; - nm_assert_addr_family(addr_family); - nm_assert(addr); - nm_assert(!server_name || !nm_str_is_empty(server_name)); - - nm_inet_ntop(addr_family, addr, sbuf); + if (!nm_dns_uri_parse(addr_family, str, &dns)) + return FALSE; - if (!server_name) { - l = g_strlcpy(result, sbuf, result_len); - } else { - d = g_snprintf(result, result_len, "%s#%s", sbuf, server_name); - nm_assert(d >= 0); - l = (gsize) d; + switch (dns.scheme) { + case NM_DNS_URI_SCHEME_TLS: + return FALSE; + case NM_DNS_URI_SCHEME_NONE: + NM_SET_OUT(out_addr, dns.addr); + if (out_addrstr) { + nm_inet_ntop(dns.addr_family, &dns.addr, out_addrstr); + } + return TRUE; + case NM_DNS_URI_SCHEME_UDP: + if (dns.port != -1 && dns.port != 53) + return FALSE; + if (dns.interface[0]) + return FALSE; + NM_SET_OUT(out_addr, dns.addr); + if (out_addrstr) { + nm_inet_ntop(dns.addr_family, &dns.addr, out_addrstr); + } + return TRUE; + case NM_DNS_URI_SCHEME_UNKNOWN: + default: + return FALSE; } - - return l < result_len ? result : NULL; } +/* @nm_dns_uri_normalize: + * @addr_family: the address family, or AF_UNSPEC to autodetect it + * @str: the name server URI string + * @out_free: the newly-allocated string to set on return, or %NULL + * + * Returns the "normal" representation for the given name server URI. + * Note that a plain name server (DNS over UDP on port 53) is always + * represented in the "legacy" (non-URI) form. + * + * Returns: the normalized DNS URI + */ const char * -nm_utils_dnsname_normalize(int addr_family, const char *dns, char **out_free) +nm_dns_uri_normalize(int addr_family, const char *str, char **out_free) { - char sbuf[NM_INET_ADDRSTRLEN]; - const char *server_name; - char *s; - NMIPAddr a; - gsize l; + NMDnsServer dns; + char addrstr[NM_INET_ADDRSTRLEN]; + char portstr[32]; + char *ret; + gsize len; nm_assert_addr_family_or_unspec(addr_family); - nm_assert(dns); + nm_assert(str); nm_assert(out_free && !*out_free); - if (!nm_utils_dnsname_parse(addr_family, dns, &addr_family, &a, &server_name)) + if (!nm_dns_uri_parse(addr_family, str, &dns)) return NULL; - nm_inet_ntop(addr_family, &a, sbuf); + nm_inet_ntop(dns.addr_family, &dns.addr, addrstr); - l = strlen(sbuf); + if (dns.port != -1) { + nm_assert(dns.port >= 0 && dns.port <= 65535); + g_snprintf(portstr, sizeof(portstr), "%d", dns.port); + } - /* In the vast majority of cases, the name is in fact normalized. Check - * whether it is, and don't duplicate the string. */ - if (strncmp(dns, sbuf, l) == 0) { - if (server_name) { - if (dns[l] == '#' && nm_streq(&dns[l + 1], server_name)) - return dns; - } else { - if (dns[l] == '\0') - return dns; + switch (dns.scheme) { + case NM_DNS_URI_SCHEME_NONE: + len = strlen(addrstr); + /* In the vast majority of cases, the name is in fact normalized. Check + * whether it is, and don't duplicate the string. */ + if (strncmp(str, addrstr, len) == 0) { + if (dns.servername) { + if (str[len] == '#' && nm_streq(&str[len + 1], dns.servername)) + return str; + } else { + if (str[len] == '\0') + return str; + } + } + + if (!dns.servername) + ret = g_strdup(addrstr); + else + ret = g_strconcat(addrstr, "#", dns.servername, NULL); + break; + case NM_DNS_URI_SCHEME_UDP: + if (dns.interface[0] || dns.port != -1) { + ret = g_strdup_printf("dns+udp://%s%s%s%s%s%s%s", + dns.addr_family == AF_INET6 ? "[" : "", + addrstr, + dns.interface[0] ? "%" : "", + dns.interface[0] ? dns.interface : "", + dns.addr_family == AF_INET6 ? "]" : "", + dns.port != -1 ? ":" : "", + dns.port != -1 ? portstr : ""); + break; } + ret = g_strdup_printf("%s%s%s", addrstr, dns.servername ? "#" : "", dns.servername ?: ""); + break; + case NM_DNS_URI_SCHEME_TLS: + ret = g_strdup_printf("dns+tls://%s%s%s%s%s%s%s%s%s", + dns.addr_family == AF_INET6 ? "[" : "", + addrstr, + dns.interface[0] ? "%%" : "", + dns.interface[0] ? dns.interface : "", + dns.addr_family == AF_INET6 ? "]" : "", + dns.port != -1 ? ":" : "", + dns.port != -1 ? portstr : "", + dns.servername ? "#" : "", + dns.servername ?: ""); + break; + case NM_DNS_URI_SCHEME_UNKNOWN: + default: + nm_assert_not_reached(); + ret = NULL; } - if (!server_name) - s = g_strdup(sbuf); - else - s = g_strconcat(sbuf, "#", server_name, NULL); + *out_free = ret; - *out_free = s; - return s; + return ret; } /*****************************************************************************/ diff --git a/src/libnm-core-aux-intern/nm-libnm-core-utils.h b/src/libnm-core-aux-intern/nm-libnm-core-utils.h index 454fe4b3..9d1637a2 100644 --- a/src/libnm-core-aux-intern/nm-libnm-core-utils.h +++ b/src/libnm-core-aux-intern/nm-libnm-core-utils.h @@ -277,6 +277,17 @@ gboolean nm_utils_validate_dhcp_dscp(const char *dscp, GError **error); /*****************************************************************************/ +#define NM_MIN_FINITE_LEASE_TIME 120 +#define NM_MAX_FINITE_LEASE_TIME (3600 * 24 * 365) +#define NM_INFINITE_LEASE_TIME "infinity" + +gboolean nm_utils_validate_shared_dhcp_range(const char *shared_dhcp_range, + GPtrArray *addresses, + GError **error); +gboolean nm_utils_validate_shared_dhcp_lease_time(int shared_dhcp_lease_time, GError **error); + +/*****************************************************************************/ + #define NM_SETTINGS_CONNECTION_PERMISSION_USER "user" #define NM_SETTINGS_CONNECTION_PERMISSION_USER_PREFIX "user:" @@ -301,32 +312,26 @@ NMMptcpFlags nm_mptcp_flags_normalize(NMMptcpFlags flags); /*****************************************************************************/ -gboolean nm_utils_dnsname_parse(int addr_family, - const char *dns, - int *out_addr_family, - gpointer /* (NMIPAddr **) */ out_addr, - const char **out_servername); - -#define nm_utils_dnsname_parse_assert(addr_family, dns, out_addr_family, out_addr, out_servername) \ - ({ \ - gboolean _good; \ - \ - _good = nm_utils_dnsname_parse((addr_family), \ - (dns), \ - (out_addr_family), \ - (out_addr), \ - (out_servername)); \ - nm_assert(_good); \ - _good; \ - }) - -const char *nm_utils_dnsname_construct(int addr_family, - gconstpointer /* (const NMIPAddr *) */ addr, - const char *server_name, - char *result, - gsize result_len); - -const char *nm_utils_dnsname_normalize(int addr_family, const char *dns, char **out_free); +typedef enum { + NM_DNS_URI_SCHEME_UNKNOWN, + NM_DNS_URI_SCHEME_NONE, + NM_DNS_URI_SCHEME_UDP, + NM_DNS_URI_SCHEME_TLS, +} NMDnsUriScheme; + +typedef struct { + NMIPAddr addr; + const char *servername; + char interface[NM_IFNAMSIZ]; + NMDnsUriScheme scheme; + int addr_family; + int port; +} NMDnsServer; + +gboolean nm_dns_uri_parse(int addr_family, const char *str, NMDnsServer *out_dns); +gboolean +nm_dns_uri_parse_plain(int addr_family, const char *str, char *out_addrstr, NMIPAddr *out_addr); +const char *nm_dns_uri_normalize(int addr_family, const char *str, char **out_free); /*****************************************************************************/ diff --git a/src/libnm-core-aux-intern/tests/meson.build b/src/libnm-core-aux-intern/tests/meson.build new file mode 100644 index 00000000..5f2670b9 --- /dev/null +++ b/src/libnm-core-aux-intern/tests/meson.build @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +exe = executable( + 'test-libnm-core-utils', + 'test-libnm-core-utils.c', + include_directories: [ + libnm_core_aux_intern_inc + ], + link_with: [ + libnm_core_aux_intern, + libnm_core_impl, + libnm_base, + libnm_crypto, + libnm_systemd_shared, + libnm_log_null, + libnm_glib_aux, + libnm_std_aux, + libc_siphash, + ], + dependencies: [ + libnm_client_public_dep, + libnm_core_public_dep, + uuid_dep, + glib_dep, + dl_dep, + ], +) + +test( + 'src/libnm-core-aux-intern/tests/test-libnm-core-utils', + exe, + args: test_args + [exe.full_path()], + timeout: default_test_timeout, +) diff --git a/src/libnm-core-aux-intern/tests/test-libnm-core-utils.c b/src/libnm-core-aux-intern/tests/test-libnm-core-utils.c new file mode 100644 index 00000000..1df36841 --- /dev/null +++ b/src/libnm-core-aux-intern/tests/test-libnm-core-utils.c @@ -0,0 +1,364 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024 Advantech Czech s.r.o. + */ + +#include "libnm-glib-aux/nm-default-glib-i18n-prog.h" +#include "libnm-glib-aux/nm-test-utils.h" + +#include "nm-libnm-core-utils.h" +#include "nm-errors.h" + +static void +empty_range_valid_for_null_addresses(void) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + gs_free_error GError *error = NULL; + gboolean result; + + result = nm_utils_validate_shared_dhcp_range("", addresses, &error); + + g_assert(result); + g_assert_null(error); +} + +static void +empty_range_valid_for_empty_addresses(void) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + gs_free_error GError *error = NULL; + gboolean result; + + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + + result = nm_utils_validate_shared_dhcp_range("", addresses, &error); + + g_assert(result); + g_assert_null(error); +} + +static void +valid_range_for_single_address(void) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + gs_free_error GError *error = NULL; + gboolean result; + + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + g_ptr_array_add(addresses, nm_ip_address_new(AF_INET, "192.168.0.1", 24, NULL)); + + result = nm_utils_validate_shared_dhcp_range("192.168.0.2,192.168.0.254", addresses, &error); + + g_assert(result); + g_assert_null(error); +} + +static void +valid_range_for_second_address(void) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + gs_free_error GError *error = NULL; + gboolean result; + + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + g_ptr_array_add(addresses, nm_ip_address_new(AF_INET, "192.168.0.1", 24, &error)); + g_ptr_array_add(addresses, nm_ip_address_new(AF_INET, "192.168.1.254", 24, &error)); + + result = nm_utils_validate_shared_dhcp_range("192.168.1.2,192.168.1.254", addresses, &error); + + g_assert(result); + g_assert_null(error); +} + +static void +invalid_null_range_for_null_addresses(void) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + gs_free_error GError *error = NULL; + gboolean result; + + result = nm_utils_validate_shared_dhcp_range(NULL, addresses, &error); + + g_assert_false(result); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + +static void +invalid_null_range_for_empty_addresses(void) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + gs_free_error GError *error = NULL; + gboolean result; + + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + + result = nm_utils_validate_shared_dhcp_range("192.168.1.2,192.168.1.254", addresses, &error); + + g_assert_false(result); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + +static void +any_range_invalid_for_null_addresses(void) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + gs_free_error GError *error = NULL; + gboolean result; + + result = nm_utils_validate_shared_dhcp_range("192.168.1.2,192.168.1.254", addresses, &error); + + g_assert_false(result); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + +static void +any_range_invalid_for_empty_addresses(void) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + gs_free_error GError *error = NULL; + gboolean result; + + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + + result = nm_utils_validate_shared_dhcp_range("192.168.1.2,192.168.1.254", addresses, &error); + + g_assert_false(result); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + +static void +invalid_range_xyz(void) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + gs_free_error GError *error = NULL; + gboolean result; + + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + g_ptr_array_add(addresses, nm_ip_address_new(AF_INET, "192.168.0.1", 24, NULL)); + + result = nm_utils_validate_shared_dhcp_range("xyz", addresses, &error); + + g_assert_false(result); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + +static void +invalid_range_single_comma(void) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + gs_free_error GError *error = NULL; + gboolean result; + + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + g_ptr_array_add(addresses, nm_ip_address_new(AF_INET, "192.168.0.1", 24, NULL)); + + result = nm_utils_validate_shared_dhcp_range(",", addresses, &error); + + g_assert_false(result); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + +static void +invalid_first_address_of_range(void) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + gs_free_error GError *error = NULL; + gboolean result; + + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + g_ptr_array_add(addresses, nm_ip_address_new(AF_INET, "192.168.0.1", 24, NULL)); + + result = nm_utils_validate_shared_dhcp_range("xyz,192.168.0.100", addresses, &error); + + g_assert_false(result); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + +static void +invalid_second_address_of_range(void) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + gs_free_error GError *error = NULL; + gboolean result; + + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + g_ptr_array_add(addresses, nm_ip_address_new(AF_INET, "192.168.0.1", 24, NULL)); + + result = nm_utils_validate_shared_dhcp_range("192.168.0.100,xyz", addresses, &error); + + g_assert_false(result); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + +static void +invalid_inverted_range(void) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + gs_free_error GError *error = NULL; + gboolean result; + + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + g_ptr_array_add(addresses, nm_ip_address_new(AF_INET, "192.168.0.1", 24, NULL)); + + result = nm_utils_validate_shared_dhcp_range("192.168.0.200,192.168.0.100", addresses, &error); + + g_assert_false(result); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + +static void +invalid_range_outside_address_space(void) +{ + gs_unref_ptrarray GPtrArray *addresses = NULL; + gs_free_error GError *error = NULL; + gboolean result; + + addresses = g_ptr_array_new_with_free_func((GDestroyNotify) nm_ip_address_unref); + g_ptr_array_add(addresses, nm_ip_address_new(AF_INET, "192.168.0.1", 24, NULL)); + + result = nm_utils_validate_shared_dhcp_range("192.168.1.2,192.168.1.100", addresses, &error); + + g_assert_false(result); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + +/*****************************************************************************/ + +static void +valid_zero_lease_time(void) +{ + gs_free_error GError *error = NULL; + gboolean result; + + result = nm_utils_validate_shared_dhcp_lease_time(0, &error); + + g_assert(result); + g_assert_null(error); +} + +static void +minimal_valid_lease_time(void) +{ + gs_free_error GError *error = NULL; + gboolean result; + + result = nm_utils_validate_shared_dhcp_lease_time(NM_MIN_FINITE_LEASE_TIME, &error); + + g_assert(result); + g_assert_null(error); +} + +static void +middle_valid_lease_time(void) +{ + gs_free_error GError *error = NULL; + gboolean result; + + result = nm_utils_validate_shared_dhcp_lease_time( + (NM_MIN_FINITE_LEASE_TIME + NM_MAX_FINITE_LEASE_TIME) / 2, + &error); + + g_assert(result); + g_assert_null(error); +} + +static void +maximal_valid_lease_time(void) +{ + gs_free_error GError *error = NULL; + gboolean result; + + result = nm_utils_validate_shared_dhcp_lease_time(NM_MAX_FINITE_LEASE_TIME, &error); + + g_assert(result); + g_assert_null(error); +} + +static void +infinite_lease_time(void) +{ + gs_free_error GError *error = NULL; + gboolean result; + + result = nm_utils_validate_shared_dhcp_lease_time(G_MAXINT32, &error); + + g_assert(result); + g_assert_null(error); +} + +static void +too_small_lease_time(void) +{ + gs_free_error GError *error = NULL; + gboolean result; + + result = nm_utils_validate_shared_dhcp_lease_time(1, &error); + + g_assert_false(result); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + +static void +too_large_lease_time(void) +{ + gs_free_error GError *error = NULL; + gboolean result; + + result = nm_utils_validate_shared_dhcp_lease_time(NM_MAX_FINITE_LEASE_TIME + 1, &error); + + g_assert_false(result); + g_assert_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY); +} + +/*****************************************************************************/ + +NMTST_DEFINE(); + +int +main(int argc, char **argv) +{ + nmtst_init(&argc, &argv, TRUE); + + g_test_add_func("/core/utils/shared_dhcp_range/empty_range_valid_for_null_addresses", + empty_range_valid_for_null_addresses); + g_test_add_func("/core/utils/shared_dhcp_range/empty_range_valid_for_empty_addresses", + empty_range_valid_for_empty_addresses); + g_test_add_func("/core/utils/shared_dhcp_range/valid_range_for_single_address", + valid_range_for_single_address); + g_test_add_func("/core/utils/shared_dhcp_range/valid_range_for_second_address", + valid_range_for_second_address); + g_test_add_func("/core/utils/shared_dhcp_range/invalid_null_range_for_null_addresses", + invalid_null_range_for_null_addresses); + g_test_add_func("/core/utils/shared_dhcp_range/invalid_null_range_for_empty_addresses", + invalid_null_range_for_empty_addresses); + g_test_add_func("/core/utils/shared_dhcp_range/any_range_invalid_for_null_addresses", + any_range_invalid_for_null_addresses); + g_test_add_func("/core/utils/shared_dhcp_range/any_range_invalid_for_empty_addresses", + any_range_invalid_for_empty_addresses); + g_test_add_func("/core/utils/shared_dhcp_range/invalid_range_xyz", invalid_range_xyz); + g_test_add_func("/core/utils/shared_dhcp_range/invalid_range_single_comma", + invalid_range_single_comma); + g_test_add_func("/core/utils/shared_dhcp_range/invalid_first_address_of_range", + invalid_first_address_of_range); + g_test_add_func("/core/utils/shared_dhcp_range/invalid_second_address_of_range", + invalid_second_address_of_range); + g_test_add_func("/core/utils/shared_dhcp_range/invalid_inverted_range", invalid_inverted_range); + g_test_add_func("/core/utils/shared_dhcp_range/invalid_range_outside_address_space", + invalid_range_outside_address_space); + + g_test_add_func("/core/utils/shared_dhcp_lease_time/valid_zero_lease_time", + valid_zero_lease_time); + g_test_add_func("/core/utils/shared_dhcp_lease_time/minimal_valid_lease_time", + minimal_valid_lease_time); + g_test_add_func("/core/utils/shared_dhcp_lease_time/middle_valid_lease_time", + middle_valid_lease_time); + g_test_add_func("/core/utils/shared_dhcp_lease_time/maximal_valid_lease_time", + maximal_valid_lease_time); + g_test_add_func("/core/utils/shared_dhcp_lease_time/infinite_lease_time", infinite_lease_time); + g_test_add_func("/core/utils/shared_dhcp_lease_time/too_small_lease_time", + too_small_lease_time); + g_test_add_func("/core/utils/shared_dhcp_lease_time/too_large_lease_time", + too_large_lease_time); + + return g_test_run(); +} 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 6d2b9254..e0ce4ac4 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 @@ -826,6 +826,18 @@ dbus-type="s" gprop-type="gchararray" /> + <property name="ip-ping-addresses" + dbus-type="as" + gprop-type="GStrv" + /> + <property name="ip-ping-addresses-require-all" + dbus-type="i" + gprop-type="gint" + /> + <property name="ip-ping-timeout" + dbus-type="u" + gprop-type="guint" + /> <property name="lldp" dbus-type="i" gprop-type="gint" @@ -1349,6 +1361,10 @@ dbus-type="u" is-setting-option="1" /> + <property name="fec-mode" + dbus-type="u" + is-setting-option="1" + /> </setting> <setting name="generic" gtype="NMSettingGeneric" @@ -1389,6 +1405,44 @@ dbus-type="b" gprop-type="gboolean" /> + <property name="initial-eps-bearer-noauth" + dbus-type="b" + gprop-type="gboolean" + /> + <property name="initial-eps-bearer-password" + is-secret="1" + dbus-type="s" + gprop-type="gchararray" + /> + <property name="initial-eps-bearer-password-flags" + is-secret-flags="1" + dbus-type="u" + gprop-type="NMSettingSecretFlags" + /> + <property name="initial-eps-bearer-refuse-chap" + dbus-type="b" + gprop-type="gboolean" + /> + <property name="initial-eps-bearer-refuse-eap" + dbus-type="b" + gprop-type="gboolean" + /> + <property name="initial-eps-bearer-refuse-mschap" + dbus-type="b" + gprop-type="gboolean" + /> + <property name="initial-eps-bearer-refuse-mschapv2" + dbus-type="b" + gprop-type="gboolean" + /> + <property name="initial-eps-bearer-refuse-pap" + dbus-type="b" + gprop-type="gboolean" + /> + <property name="initial-eps-bearer-username" + dbus-type="s" + gprop-type="gchararray" + /> <property name="mtu" dbus-type="u" gprop-type="guint" @@ -1610,6 +1664,10 @@ dbus-type="s" gprop-type="gchararray" /> + <property name="dhcp-ipv6-only-preferred" + dbus-type="i" + gprop-type="gint" + /> <property name="dhcp-reject-servers" dbus-type="as" gprop-type="GStrv" @@ -1618,6 +1676,10 @@ dbus-type="b" gprop-type="gboolean" /> + <property name="dhcp-send-hostname-v2" + dbus-type="i" + gprop-type="gint" + /> <property name="dhcp-send-release" dbus-type="i" gprop-type="NMTernary" @@ -1697,6 +1759,10 @@ dbus-type="u" gprop-type="guint" /> + <property name="routed-dns" + dbus-type="i" + gprop-type="gint" + /> <property name="routes" dbus-type="aau" dbus-deprecated="1" @@ -1705,6 +1771,14 @@ <property name="routing-rules" dbus-type="aa{sv}" /> + <property name="shared-dhcp-lease-time" + dbus-type="i" + gprop-type="gint" + /> + <property name="shared-dhcp-range" + dbus-type="s" + gprop-type="gchararray" + /> </setting> <setting name="ipv6" gtype="NMSettingIP6Config" @@ -1761,6 +1835,10 @@ dbus-type="b" gprop-type="gboolean" /> + <property name="dhcp-send-hostname-v2" + dbus-type="i" + gprop-type="gint" + /> <property name="dhcp-send-release" dbus-type="i" gprop-type="NMTernary" @@ -1844,6 +1922,10 @@ dbus-type="u" gprop-type="guint" /> + <property name="routed-dns" + dbus-type="i" + gprop-type="gint" + /> <property name="routes" dbus-type="a(ayuayu)" dbus-deprecated="1" @@ -1852,6 +1934,14 @@ <property name="routing-rules" dbus-type="aa{sv}" /> + <property name="shared-dhcp-lease-time" + dbus-type="i" + gprop-type="gint" + /> + <property name="shared-dhcp-range" + dbus-type="s" + gprop-type="gchararray" + /> <property name="temp-preferred-lifetime" dbus-type="i" gprop-type="gint" @@ -1865,6 +1955,26 @@ gprop-type="gchararray" /> </setting> + <setting name="ipvlan" + gtype="NMSettingIpvlan" + > + <property name="mode" + dbus-type="u" + gprop-type="guint" + /> + <property name="parent" + dbus-type="s" + gprop-type="gchararray" + /> + <property name="private" + dbus-type="b" + gprop-type="gboolean" + /> + <property name="vepa" + dbus-type="b" + gprop-type="gboolean" + /> + </setting> <setting name="link" gtype="NMSettingLink" > diff --git a/src/libnm-core-impl/meson.build b/src/libnm-core-impl/meson.build index e1f11f32..e068d6bd 100644 --- a/src/libnm-core-impl/meson.build +++ b/src/libnm-core-impl/meson.build @@ -25,6 +25,7 @@ libnm_core_settings_sources = files( 'nm-setting-ip-tunnel.c', 'nm-setting-ip4-config.c', 'nm-setting-ip6-config.c', + 'nm-setting-ipvlan.c', 'nm-setting-link.c', 'nm-setting-loopback.c', 'nm-setting-macsec.c', diff --git a/src/libnm-core-impl/nm-connection-private.h b/src/libnm-core-impl/nm-connection-private.h index 9f9007b6..38619bd7 100644 --- a/src/libnm-core-impl/nm-connection-private.h +++ b/src/libnm-core-impl/nm-connection-private.h @@ -29,6 +29,10 @@ const char *_nm_connection_detect_bluetooth_type(NMConnection *self); gboolean _nm_setting_connection_verify_secondaries(GArray *secondaries, GError **error); +gboolean _nm_setting_connection_verify_no_duplicate_addresses(GArray *secondaries, GError **error); + +int _get_ip_address_family(const char *ip_address); + gboolean _nm_connection_verify_required_interface_name(NMConnection *connection, GError **error); int _nm_setting_ovs_interface_verify_interface_type(NMSettingOvsInterface *self, diff --git a/src/libnm-core-impl/nm-connection.c b/src/libnm-core-impl/nm-connection.c index 6dace2b7..61a20a13 100644 --- a/src/libnm-core-impl/nm-connection.c +++ b/src/libnm-core-impl/nm-connection.c @@ -89,7 +89,7 @@ _nm_connection_get_private_from_qdata(NMConnection *connection) priv = g_object_get_qdata((GObject *) connection, key); if (G_UNLIKELY(!priv)) { priv = g_slice_new(NMConnectionPrivate); - *priv = (NMConnectionPrivate){ + *priv = (NMConnectionPrivate) { .self = connection, }; g_object_set_qdata_full((GObject *) connection, key, priv, _nm_connection_private_free); @@ -959,6 +959,40 @@ out: return FALSE; } +gboolean +_nm_setting_connection_verify_no_duplicate_addresses(GArray *addresses, GError **error) +{ + guint i, j; + + if (addresses->len <= 1) { + return TRUE; + } else { + for (i = 0; i < addresses->len - 1; i++) { + for (j = i + 1; j < addresses->len; j++) { + if (nm_streq0(nm_g_array_index(addresses, const char *, i), + nm_g_array_index(addresses, const char *, j))) + return FALSE; + } + } + } + + return TRUE; +} + +int +_get_ip_address_family(const char *ip_address) +{ + struct in_addr ipv4_addr; + struct in6_addr ipv6_addr; + + if (inet_pton(AF_INET, ip_address, &ipv4_addr)) + return AF_INET; + else if (inet_pton(AF_INET6, ip_address, &ipv6_addr)) + return AF_INET6; + else + return -1; +} + static gboolean _normalize_connection_secondaries(NMConnection *self) { @@ -998,6 +1032,48 @@ _normalize_connection_secondaries(NMConnection *self) } static gboolean +_normalize_connection_ip_ping_addresses(NMConnection *self) +{ + NMSettingConnection *s_con = nm_connection_get_setting_connection(self); + GArray *addresses; + gs_strfreev char **strv = NULL; + guint i, j, k; + + nm_assert(s_con); + + addresses = _nm_setting_connection_get_ip_ping_addresses(s_con); + if (nm_g_array_len(addresses) == 0) + return FALSE; + + if (_nm_setting_connection_verify_no_duplicate_addresses(addresses, NULL)) + return FALSE; + + strv = nm_strvarray_get_strv_notempty_dup(addresses, NULL); + + for (i = 0, j = 0; strv[i]; i++) { + gboolean found = FALSE; + + for (k = 0; k < j; k++) { + if (nm_streq0(strv[i], strv[k])) { + found = TRUE; + break; + } + } + + if (found) { + continue; + } + + strv[j++] = strv[i]; + } + strv[j] = NULL; + + g_object_set(s_con, NM_SETTING_CONNECTION_IP_PING_ADDRESSES, strv, NULL); + + return TRUE; +} + +static gboolean _normalize_connection_type(NMConnection *self) { NMSettingConnection *s_con = nm_connection_get_setting_connection(self); @@ -1186,6 +1262,7 @@ _normalize_ip_config(NMConnection *self, GHashTable *parameters) NMSetting *setting; gboolean changed = FALSE; guint num, i; + int dhcp_send_hostname_v2; s_ip4 = nm_connection_get_setting_ip4_config(self); s_ip6 = nm_connection_get_setting_ip6_config(self); @@ -1241,6 +1318,16 @@ _normalize_ip_config(NMConnection *self, GHashTable *parameters) nm_setting_ip_config_remove_address(s_ip4, i); changed = TRUE; } + + dhcp_send_hostname_v2 = nm_setting_ip_config_get_dhcp_send_hostname_v2(s_ip4); + if (dhcp_send_hostname_v2 != NM_TERNARY_DEFAULT + && dhcp_send_hostname_v2 != nm_setting_ip_config_get_dhcp_send_hostname(s_ip4)) { + g_object_set(s_ip4, + NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, + dhcp_send_hostname_v2, + NULL); + changed = TRUE; + } } } else { if (s_ip4) { @@ -1315,6 +1402,16 @@ _normalize_ip_config(NMConnection *self, GHashTable *parameters) g_object_set(s_ip6, NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); changed = TRUE; } + + dhcp_send_hostname_v2 = nm_setting_ip_config_get_dhcp_send_hostname_v2(s_ip6); + if (dhcp_send_hostname_v2 != NM_TERNARY_DEFAULT + && dhcp_send_hostname_v2 != nm_setting_ip_config_get_dhcp_send_hostname(s_ip6)) { + g_object_set(s_ip6, + NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, + dhcp_send_hostname_v2, + NULL); + changed = TRUE; + } } } else { if (s_ip6) { @@ -2028,6 +2125,7 @@ _connection_normalize(NMConnection *connection, was_modified |= _normalize_connection_type(connection); was_modified |= _normalize_connection_port_type(connection); was_modified |= _normalize_connection_secondaries(connection); + was_modified |= _normalize_connection_ip_ping_addresses(connection); was_modified |= _normalize_connection(connection); was_modified |= _normalize_required_settings(connection); was_modified |= _normalize_invalid_port_port_settings(connection); @@ -3176,6 +3274,7 @@ nm_connection_is_virtual(NMConnection *connection) NM_SETTING_DUMMY_SETTING_NAME, NM_SETTING_HSR_SETTING_NAME, NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_SETTING_IPVLAN_SETTING_NAME, NM_SETTING_MACSEC_SETTING_NAME, NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_OVS_BRIDGE_SETTING_NAME, diff --git a/src/libnm-core-impl/nm-keyfile-utils.c b/src/libnm-core-impl/nm-keyfile-utils.c index 95073bcc..fdf00677 100644 --- a/src/libnm-core-impl/nm-keyfile-utils.c +++ b/src/libnm-core-impl/nm-keyfile-utils.c @@ -682,22 +682,3 @@ nm_keyfile_key_decode(const char *key, char **out_to_free) #endif return name; } - -void -nm_keyfile_add_group(GKeyFile *keyfile, const char *group) -{ - nm_assert(keyfile); - nm_assert(group); - - /* You can only call this function if the group doesn't exist yet. - * Because, we are about to add a dummy key, so we would have to - * be sure that the key doesn't exist. */ - nm_assert(!g_key_file_has_group(keyfile, group)); - - /* Ensure the group is present. - * There is no API for that, so add and remove a dummy key. - * For a profile it matters whether a setting is present or not, - * and we need to ensure that we persist the presence of the setting to keyfile*/ - g_key_file_set_value(keyfile, group, ".X", "1"); - g_key_file_remove_key(keyfile, group, ".X", NULL); -} diff --git a/src/libnm-core-impl/nm-keyfile.c b/src/libnm-core-impl/nm-keyfile.c index 8dadf3cd..e4559e3c 100644 --- a/src/libnm-core-impl/nm-keyfile.c +++ b/src/libnm-core-impl/nm-keyfile.c @@ -18,6 +18,7 @@ #include <linux/if_ether.h> #include <linux/if_infiniband.h> +#include "libnm-glib-aux/nm-keyfile-aux.h" #include "libnm-glib-aux/nm-uuid.h" #include "libnm-glib-aux/nm-str-buf.h" #include "libnm-glib-aux/nm-secret-utils.h" @@ -132,7 +133,7 @@ _nm_printf(5, 6) static void _read_handle_warn(KeyfileReaderInfo *info, info, kf_key, cur_property); - handler_data.warn = (NMKeyfileHandlerDataWarn){ + handler_data.warn = (NMKeyfileHandlerDataWarn) { .severity = severity, .message = NULL, .fmt = fmt, @@ -186,7 +187,7 @@ _nm_printf(6, 7) static void _write_handle_warn(KeyfileWriterInfo *info, cur_property, setting, kf_key); - handler_data.warn = (NMKeyfileHandlerDataWarn){ + handler_data.warn = (NMKeyfileHandlerDataWarn) { .severity = severity, .message = NULL, .fmt = fmt, @@ -915,7 +916,7 @@ _build_list_create(GKeyFile *keyfile, if (G_UNLIKELY(!build_list)) build_list = g_new(BuildListData, n_keys - i_keys); - build_list[build_list_len++] = (BuildListData){ + build_list[build_list_len++] = (BuildListData) { .s_key = s_key, .key_idx = key_idx, .key_type = key_type, @@ -939,6 +940,31 @@ _build_list_create(GKeyFile *keyfile, } static void +gateway_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key) +{ + const char *setting_name = nm_setting_get_name(setting); + gs_free char *gateway = NULL; + const char *old_gateway; + + gateway = nm_keyfile_plugin_kf_get_string(info->keyfile, setting_name, key, NULL); + if (!gateway) + return; + + old_gateway = nm_setting_ip_config_get_gateway(NM_SETTING_IP_CONFIG(setting)); + if (old_gateway && !nm_streq0(gateway, old_gateway)) { + read_handle_warn(info, + key, + NM_SETTING_IP_CONFIG_GATEWAY, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("ignoring gateway \"%s\" from \"address*\" keys because the " + "\"gateway\" key is set"), + old_gateway); + } + + g_object_set(setting, NM_SETTING_IP_CONFIG_GATEWAY, gateway, NULL); +} + +static void ip_address_or_route_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *setting_key) { const char *setting_name = nm_setting_get_name(setting); @@ -1132,7 +1158,7 @@ ip_dns_parser(KeyfileReaderInfo *info, NMSetting *setting, const char *key) addr_family = NM_SETTING_IP_CONFIG_GET_ADDR_FAMILY(setting); for (i = 0, n = 0; i < length; i++) { - if (!nm_utils_dnsname_parse(addr_family, list[i], NULL, NULL, NULL)) { + if (!nm_dns_uri_parse(addr_family, list[i], NULL)) { if (!read_handle_warn(info, key, key, @@ -2263,11 +2289,7 @@ ip6_addr_gen_mode_writer(KeyfileWriterInfo *info, } static void -write_ip_values(GKeyFile *file, - const char *setting_name, - GPtrArray *array, - const char *gateway, - gboolean is_route) +write_ip_values(GKeyFile *file, const char *setting_name, GPtrArray *array, gboolean is_route) { if (array->len > 0) { nm_auto_str_buf NMStrBuf output = NM_STR_BUF_INIT(2 * INET_ADDRSTRLEN + 10, FALSE); @@ -2300,7 +2322,7 @@ write_ip_values(GKeyFile *file, addr = nm_ip_address_get_address(address); plen = nm_ip_address_get_prefix(address); - gw = (i == 0) ? gateway : NULL; + gw = NULL; } nm_str_buf_set_size(&output, 0, FALSE, FALSE); @@ -2351,11 +2373,10 @@ addr_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const { GPtrArray *array; const char *setting_name = nm_setting_get_name(setting); - const char *gateway = nm_setting_ip_config_get_gateway(NM_SETTING_IP_CONFIG(setting)); array = (GPtrArray *) g_value_get_boxed(value); if (array && array->len) - write_ip_values(info->keyfile, setting_name, array, gateway, FALSE); + write_ip_values(info->keyfile, setting_name, array, FALSE); } static void @@ -2366,7 +2387,7 @@ route_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const array = (GPtrArray *) g_value_get_boxed(value); if (array && array->len) - write_ip_values(info->keyfile, setting_name, array, NULL, TRUE); + write_ip_values(info->keyfile, setting_name, array, TRUE); } static void @@ -2482,7 +2503,7 @@ wired_s390_options_writer_full(KeyfileWriterInfo *info, /* groups in the keyfile are ordered. When we are about to add [ethernet-s390-options], * we want to also have an [ethernet] group, first. */ - nm_keyfile_add_group(info->keyfile, setting_alias ?: NM_SETTING_WIRED_SETTING_NAME); + nm_key_file_add_group(info->keyfile, setting_alias ?: NM_SETTING_WIRED_SETTING_NAME); } for (i = 0; i < n; i++) { @@ -2882,7 +2903,7 @@ cert_writer(KeyfileWriterInfo *info, NMSetting *setting, const char *key, const vtable->setting_key, setting, key); - handler_data.write_cert = (NMKeyfileHandlerDataWriteCert){ + handler_data.write_cert = (NMKeyfileHandlerDataWriteCert) { .vtable = vtable, }; @@ -2944,11 +2965,11 @@ struct _ParseInfoProperty { }; #define PARSE_INFO_PROPERTY(_property_name, ...) \ - (&((const ParseInfoProperty){.property_name = _property_name, __VA_ARGS__})) + (&((const ParseInfoProperty) {.property_name = _property_name, __VA_ARGS__})) -#define PARSE_INFO_PROPERTIES(...) \ - .properties = ((const ParseInfoProperty *const[]){ \ - __VA_ARGS__ NULL, \ +#define PARSE_INFO_PROPERTIES(...) \ + .properties = ((const ParseInfoProperty *const[]) { \ + __VA_ARGS__ NULL, \ }) typedef struct { @@ -2956,7 +2977,7 @@ typedef struct { } ParseInfoSetting; #define PARSE_INFO_SETTING(setting_type, ...) \ - [setting_type] = (&((const ParseInfoSetting){__VA_ARGS__})) + [setting_type] = (&((const ParseInfoSetting) {__VA_ARGS__})) static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { PARSE_INFO_SETTING( @@ -3060,7 +3081,7 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { .parser = ip_dns_parser, .writer = dns_writer, ), PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_DNS_OPTIONS, .always_write = TRUE, ), - PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_GATEWAY, .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_GATEWAY, .parser = gateway_parser, ), PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTES, .parser_no_check_key = TRUE, .parser = ip_address_or_route_parser, @@ -3088,7 +3109,7 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = { .parser = ip_dns_parser, .writer = dns_writer, ), PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_DNS_OPTIONS, .always_write = TRUE, ), - PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_GATEWAY, .writer_skip = TRUE, ), + PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_GATEWAY, .parser = gateway_parser, ), PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTES, .parser_no_check_key = TRUE, .parser = ip_address_or_route_parser, @@ -3549,6 +3570,62 @@ read_one_setting_value(KeyfileReaderInfo *info, } static void +_read_handle_renamed_properties(KeyfileReaderInfo *info) +{ + GKeyFile *kf = info->keyfile; + const char *group = info->group; + gs_free_error GError *error = NULL; + + if (NM_IN_STRSET(group, "ipv4", "ipv6")) { + /* dhcp-send-hostname is stored as dhcp-send-hostname-deprecated + * dhcp-send-hostname-v2 is stored as dhcp-send-hostname + * Do the conversion back. Also, accept boolean values for -v2 to + * maintain backwards compatibility with keyfiles written with the + * deprecated property in mind + */ + if (g_key_file_has_key(kf, group, "dhcp-send-hostname", NULL)) { + gboolean val_bool; + int val; + + val = g_key_file_get_integer(kf, group, "dhcp-send-hostname", &error); + if (error) { + g_clear_error(&error); + val_bool = g_key_file_get_boolean(kf, group, "dhcp-send-hostname", &error); + if (!error) + val = val_bool ? 1 : 0; + else + read_handle_warn(info, + NULL, + NULL, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid value for '%s.dhcp-send-hostname'"), + info->group); + } + + g_key_file_remove_key(kf, group, "dhcp-send-hostname", NULL); + if (!error) + g_key_file_set_integer(kf, group, "dhcp-send-hostname-v2", val); + } + + if (g_key_file_has_key(kf, group, "dhcp-send-hostname-deprecated", NULL)) { + gs_free char *val = NULL; + + val = g_key_file_get_value(kf, group, "dhcp-send-hostname-deprecated", NULL); + g_key_file_remove_key(kf, group, "dhcp-send-hostname-deprecated", NULL); + if (val) + g_key_file_set_value(kf, group, "dhcp-send-hostname", val); + else + read_handle_warn(info, + NULL, + NULL, + NM_KEYFILE_WARN_SEVERITY_WARN, + _("invalid value for '%s.dhcp-send-hostname-deprecated'"), + info->group); + } + } +} + +static void _read_setting(KeyfileReaderInfo *info) { const NMSettInfoSetting *sett_info; @@ -3576,6 +3653,8 @@ _read_setting(KeyfileReaderInfo *info) info->setting = setting; + _read_handle_renamed_properties(info); + sett_info = _nm_setting_class_get_sett_info(NM_SETTING_GET_CLASS(setting)); if (sett_info->detail.gendata_info) { @@ -3950,7 +4029,7 @@ nm_keyfile_read(GKeyFile *keyfile, connection = nm_simple_connection_new(); - info = (KeyfileReaderInfo){ + info = (KeyfileReaderInfo) { .connection = connection, .keyfile = keyfile, .base_dir = base_dir, @@ -4084,11 +4163,23 @@ write_setting_value(KeyfileWriterInfo *info, NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST)) return; - value = (GValue){0}; + value = (GValue) {0}; g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(property_info->param_spec)); g_object_get_property(G_OBJECT(setting), property_info->param_spec->name, &value); + /* To prevent any confusion from the user regarding the v2 suffix, + * dhcp-send-hostname is stored as dhcp-send-hostname-deprecated + * and dhcp-send-hostname-v2 is stored as dhcp-send-hostname + * in the keyfile. + */ + if (NM_IS_SETTING_IP4_CONFIG(setting) || NM_IS_SETTING_IP6_CONFIG(setting)) { + if (nm_streq(key, NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME_V2)) + key = "dhcp-send-hostname"; + else if (nm_streq(key, NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME)) + key = "dhcp-send-hostname-deprecated"; + } + if ((!pip || !pip->writer_persist_default) && g_param_value_defaults(property_info->param_spec, &value)) { nm_assert(!g_key_file_has_key(info->keyfile, setting_info->setting_name, key, NULL)); @@ -4304,7 +4395,7 @@ nm_keyfile_write(NMConnection *connection, keyfile = g_key_file_new(); - info = (KeyfileWriterInfo){ + info = (KeyfileWriterInfo) { .connection = connection, .keyfile = keyfile, .error = NULL, @@ -4385,7 +4476,7 @@ nm_keyfile_write(NMConnection *connection, || g_key_file_has_group(info.keyfile, setting_name)) { /* we have a section for the setting. Nothing to do. */ } else { - nm_keyfile_add_group(info.keyfile, setting_alias ?: setting_name); + nm_key_file_add_group(info.keyfile, setting_alias ?: setting_name); } if (NM_IS_SETTING_WIREGUARD(setting)) { diff --git a/src/libnm-core-impl/nm-meta-setting-base-impl.c b/src/libnm-core-impl/nm-meta-setting-base-impl.c index 34a7d22e..37cb61f1 100644 --- a/src/libnm-core-impl/nm-meta-setting-base-impl.c +++ b/src/libnm-core-impl/nm-meta-setting-base-impl.c @@ -35,6 +35,7 @@ #include "nm-setting-ip-tunnel.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" +#include "nm-setting-ipvlan.h" #include "nm-setting-link.h" #include "nm-setting-loopback.h" #include "nm-setting-macsec.h" @@ -371,6 +372,13 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = { .setting_name = NM_SETTING_IP_TUNNEL_SETTING_NAME, .get_setting_gtype = nm_setting_ip_tunnel_get_type, }, + [NM_META_SETTING_TYPE_IPVLAN] = + { + .meta_type = NM_META_SETTING_TYPE_IPVLAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_IPVLAN_SETTING_NAME, + .get_setting_gtype = nm_setting_ipvlan_get_type, + }, [NM_META_SETTING_TYPE_LINK] = { .meta_type = NM_META_SETTING_TYPE_LINK, @@ -643,6 +651,7 @@ const NMMetaSettingType nm_meta_setting_types_by_priority[] = { NM_META_SETTING_TYPE_HSR, NM_META_SETTING_TYPE_INFINIBAND, NM_META_SETTING_TYPE_IP_TUNNEL, + NM_META_SETTING_TYPE_IPVLAN, NM_META_SETTING_TYPE_LOOPBACK, NM_META_SETTING_TYPE_MACSEC, NM_META_SETTING_TYPE_MACVLAN, @@ -822,7 +831,7 @@ again: for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { const NMMetaSettingInfo *m = &nm_meta_setting_infos[i]; - static_array[i] = (LookupData){ + static_array[i] = (LookupData) { .gtype = m->get_setting_gtype(), .setting_info = m, }; diff --git a/src/libnm-core-impl/nm-setting-bridge.c b/src/libnm-core-impl/nm-setting-bridge.c index 7e9a0964..c1618434 100644 --- a/src/libnm-core-impl/nm-setting-bridge.c +++ b/src/libnm-core-impl/nm-setting-bridge.c @@ -151,7 +151,7 @@ nm_bridge_vlan_new(guint16 vid_start, guint16 vid_end) g_return_val_if_fail(vid_start <= vid_end, NULL); vlan = g_slice_new(NMBridgeVlan); - *vlan = (NMBridgeVlan){ + *vlan = (NMBridgeVlan) { .refcount = 1, .vid_start = vid_start, .vid_end = vid_end, diff --git a/src/libnm-core-impl/nm-setting-connection.c b/src/libnm-core-impl/nm-setting-connection.c index 33d088bb..4a910c7f 100644 --- a/src/libnm-core-impl/nm-setting-connection.c +++ b/src/libnm-core-impl/nm-setting-connection.c @@ -63,6 +63,9 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMSettingConnection, PROP_AUTOCONNECT_PORTS, PROP_SECONDARIES, PROP_GATEWAY_PING_TIMEOUT, + PROP_IP_PING_TIMEOUT, + PROP_IP_PING_ADDRESSES, + PROP_IP_PING_ADDRESSES_REQUIRE_ALL, PROP_METERED, PROP_LLDP, PROP_MDNS, @@ -91,6 +94,7 @@ typedef struct { guint64 timestamp; int autoconnect_ports; int down_on_poweroff; + int ip_ping_addresses_require_all; int metered; gint32 autoconnect_priority; gint32 autoconnect_retries; @@ -104,6 +108,8 @@ typedef struct { gint32 wait_activation_delay; guint32 mptcp_flags; guint32 gateway_ping_timeout; + NMValueStrv ip_ping_addresses; + guint32 ip_ping_timeout; bool autoconnect; bool read_only; } NMSettingConnectionPrivate; @@ -139,7 +145,7 @@ _permission_set_stale(Permission *permission, PermType ptype, char *item_take) /* we don't inspect (clear) permission before setting. It takes a * stale instance. */ - *permission = (Permission){ + *permission = (Permission) { .ptype = ptype, .item = item_take, }; @@ -1037,6 +1043,172 @@ nm_setting_connection_get_gateway_ping_timeout(NMSettingConnection *setting) return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->gateway_ping_timeout; } +GArray * +_nm_setting_connection_get_ip_ping_addresses(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->ip_ping_addresses.arr; +} + +/** + * nm_setting_connection_get_ip_ping_address: + * @setting: the #NMSettingConnection + * @idx: the zero-based index of the ip-ping-addresses entry. + * + * Returns: the ip address string at index @idx or + * %NULL if @idx is the number of ip-ping-addresses. + * + * Since: 1.52 + **/ +const char * +nm_setting_connection_get_ip_ping_address(NMSettingConnection *setting, guint32 idx) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NULL); + + return nm_strvarray_get_idxnull_or_greturn( + NM_SETTING_CONNECTION_GET_PRIVATE(setting)->ip_ping_addresses.arr, + idx); +} + +/** + * nm_setting_connection_add_ip_ping_address: + * @setting: the #NMSettingConnection + * @address: the IP address string to add + * + * Adds a new IP address string to the ip-ping-addresses. + * + * Returns: %TRUE if the new IP address was added; %FALSE if the IP address + * was already present + * + * Since: 1.52 + **/ +gboolean +nm_setting_connection_add_ip_ping_address(NMSettingConnection *setting, const char *address) +{ + NMSettingConnectionPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), FALSE); + g_return_val_if_fail(address, FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); + + if (!nm_strvarray_ensure_and_add_unique(&priv->ip_ping_addresses.arr, address)) + return FALSE; + + _notify(setting, PROP_IP_PING_ADDRESSES); + return TRUE; +} + +/** + * nm_setting_connection_remove_ip_ping_address: + * @setting: the #NMSettingConnection + * @idx: index number of the IP address + * + * Removes the IP address at index @idx. + * + * Since: 1.52 + **/ +void +nm_setting_connection_remove_ip_ping_address(NMSettingConnection *setting, guint32 idx) +{ + NMSettingConnectionPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_CONNECTION(setting)); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); + + g_return_if_fail(idx < nm_g_array_len(priv->ip_ping_addresses.arr)); + + nm_strvarray_remove_index(priv->ip_ping_addresses.arr, idx); + _notify(setting, PROP_IP_PING_ADDRESSES); +} + +/** + * nm_setting_connection_remove_ip_ping_address_by_value: + * @setting: the #NMSettingConnection + * @address: the IP address to remove + * + * Removes the IP address @address from ip-ping-addresses. + * + * Returns: %TRUE if the IP address was found and removed; %FALSE if it was not. + * + * Since: 1.52 + **/ +gboolean +nm_setting_connection_remove_ip_ping_address_by_value(NMSettingConnection *setting, + const char *address) +{ + NMSettingConnectionPrivate *priv; + + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), FALSE); + g_return_val_if_fail(address, FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); + + if (!nm_strvarray_remove_first(priv->ip_ping_addresses.arr, address)) + return FALSE; + + _notify(setting, PROP_IP_PING_ADDRESSES); + return TRUE; +} + +/** + * nm_setting_connection_clear_ip_ping_addresses: + * @setting: the #NMSettingConnection + * + * Removes all configured ip-ping-addresses. + * + * Since: 1.52 + **/ +void +nm_setting_connection_clear_ip_ping_addresses(NMSettingConnection *setting) +{ + NMSettingConnectionPrivate *priv; + + g_return_if_fail(NM_IS_SETTING_CONNECTION(setting)); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting); + + if (nm_strvarray_clear(&priv->ip_ping_addresses.arr)) + _notify(setting, PROP_IP_PING_ADDRESSES); +} + +/** + * nm_setting_connection_get_ip_ping_timeout: + * @setting: the #NMSettingConnection + * + * Returns: the value contained in the #NMSettingConnection:ip-ping-timeout + * property. + * + * Since: 1.52 + **/ +guint32 +nm_setting_connection_get_ip_ping_timeout(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), 0); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->ip_ping_timeout; +} + +/** + * nm_setting_connection_get_ip_ping_addresses_require_all: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:ip-ping-addresses-require-all property of the connection. + * + * Returns: whether all the ip ping addresses pass the connectivity check. + * + * Since: 1.52 + **/ +NMTernary +nm_setting_connection_get_ip_ping_addresses_require_all(NMSettingConnection *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NM_TERNARY_DEFAULT); + + return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->ip_ping_addresses_require_all; +} + /** * nm_setting_connection_get_metered: * @setting: the #NMSettingConnection @@ -1610,6 +1782,176 @@ after_interface_name: } } + if (priv->ip_ping_timeout != 0 + && (!priv->ip_ping_addresses.arr || priv->ip_ping_addresses.arr->len == 0)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("can only be set if %s.%s is set"), + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_IP_PING_ADDRESSES); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_IP_PING_TIMEOUT); + return FALSE; + } + + if (priv->ip_ping_addresses.arr && priv->ip_ping_addresses.arr->len > 0) { + guint i; + + if (priv->ip_ping_timeout == 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("can only be set if %s.%s is set"), + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_IP_PING_TIMEOUT); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_IP_PING_ADDRESSES); + return FALSE; + } + + if (priv->gateway_ping_timeout != 0 && priv->ip_ping_timeout != 0) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("is incompatible with '%s'"), + NM_SETTING_CONNECTION_IP_PING_TIMEOUT); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT); + return FALSE; + } + + for (i = 0; i < priv->ip_ping_addresses.arr->len; i++) { + const char *address = nm_g_array_index(priv->ip_ping_addresses.arr, const char *, i); + int addr_family = _get_ip_address_family(address); + + if (addr_family == AF_INET) { + NMSettingIPConfig *s_ip4; + + if (connection) { + s_ip4 = nm_connection_get_setting_ip4_config(connection); + + if (s_ip4) { + const char *method = nm_setting_ip_config_get_method(s_ip4); + if (nm_streq0(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("contains IPv4 address '%s', %s.%s cannot be 'disabled'"), + address, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_METHOD); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_IP_PING_ADDRESSES); + return FALSE; + } + if (nm_setting_ip_config_get_may_fail(s_ip4)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("contains IPv4 address '%s', %s.%s cannot be 'true'"), + address, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_MAY_FAIL); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_IP_PING_ADDRESSES); + return FALSE; + } + } else { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("contains IPv4 address '%s', %s.%s must be set to 'false' " + "explicitly"), + address, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_MAY_FAIL); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_IP_PING_ADDRESSES); + return FALSE; + } + } + } else if (addr_family == AF_INET6) { + NMSettingIPConfig *s_ip6; + + if (connection) { + s_ip6 = nm_connection_get_setting_ip6_config(connection); + if (s_ip6) { + const char *method = nm_setting_ip_config_get_method(s_ip6); + if (NM_IN_STRSET(method, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP6_CONFIG_METHOD_DISABLED)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("contains IPv6 address '%s', %s.%s cannot be '%s'"), + address, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_METHOD, + method); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_IP_PING_ADDRESSES); + return FALSE; + } + if (nm_setting_ip_config_get_may_fail(s_ip6)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("contains IPv6 address '%s', %s.%s cannot be 'true'"), + address, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_MAY_FAIL); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_IP_PING_ADDRESSES); + return FALSE; + } + } else { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("contains IPv6 address '%s', %s.%s must be set to 'false' " + "explicitly"), + address, + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_MAY_FAIL); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_IP_PING_ADDRESSES); + return FALSE; + } + } + } else { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("has an invalid IP address '%s'"), + address); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_IP_PING_ADDRESSES); + return FALSE; + } + } + } + /* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */ if (!priv->uuid) { @@ -1711,6 +2053,20 @@ after_interface_name: if (!_nm_setting_connection_verify_secondaries(priv->secondaries.arr, error)) return NM_SETTING_VERIFY_NORMALIZABLE; + if (priv->ip_ping_addresses.arr && priv->ip_ping_addresses.arr->len > 0 + && !_nm_setting_connection_verify_no_duplicate_addresses(priv->ip_ping_addresses.arr, + error)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("has duplicate addresses")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_IP_PING_ADDRESSES); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + if (priv->read_only) { g_set_error_literal(error, NM_CONNECTION_ERROR, @@ -2763,6 +3119,70 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass) secondaries); /** + * NMSettingConnection:ip-ping-addresses: + * + * The property specifies a list of target IP addresses for pinging. + * When multiple targets are set, NetworkManager will start multiple ping processes + * in parallel. This property can only be set if connection.ip-ping-timeout is + * set. The ip-ping-timeout is used to delay the success of IP addressing until + * either the specified timeout (in seconds) is reached, or an target IP address replies + * to a ping. Configuring #NMSettingConnection:ip-ping-addresses may delay reaching the + * systemd's network-online.target due to waiting for the ping operations to complete or timeout. + * + * Since: 1.52 + **/ + _nm_setting_property_define_direct_strv(properties_override, + obj_properties, + NM_SETTING_CONNECTION_IP_PING_ADDRESSES, + PROP_IP_PING_ADDRESSES, + NM_SETTING_PARAM_FUZZY_IGNORE, + NULL, + NMSettingConnectionPrivate, + ip_ping_addresses); + + /** + * NMSettingConnection:ip-ping-addresses-require-all: + * + * The property determines whether it is sufficient for any ping check + * to succeed among #NMSettingConnection:ip-ping-addresses, or if all + * ping checks must succeed for #NMSettingConnection:ip-ping-addresses. + * + * Since: 1.52 + **/ + _nm_setting_property_define_direct_enum(properties_override, + obj_properties, + NM_SETTING_CONNECTION_IP_PING_ADDRESSES_REQUIRE_ALL, + PROP_IP_PING_ADDRESSES_REQUIRE_ALL, + NM_TYPE_TERNARY, + NM_TERNARY_DEFAULT, + NM_SETTING_PARAM_NONE, + NULL, + NMSettingConnectionPrivate, + ip_ping_addresses_require_all); + + /** + * NMSettingConnection:ip-ping-timeout: + * + * If greater than zero, delay success of IP addressing until either the specified + * timeout (in seconds) is reached, or a target IP address replies to a ping. The + * property specifies the timeout for the #NMSettingConnection:ip-ping-addresses. + * This property is incompatible with #NMSettingConnection:gateway-ping-timeout, + * you cannot set these two properties at the same time. + * + * Since: 1.52 + **/ + _nm_setting_property_define_direct_uint32(properties_override, + obj_properties, + NM_SETTING_CONNECTION_IP_PING_TIMEOUT, + PROP_IP_PING_TIMEOUT, + 0, + 600, + 0, + NM_SETTING_PARAM_NONE, + NMSettingConnectionPrivate, + ip_ping_timeout); + + /** * NMSettingConnection:gateway-ping-timeout: * * If greater than zero, delay success of IP addressing until either the diff --git a/src/libnm-core-impl/nm-setting-ethtool.c b/src/libnm-core-impl/nm-setting-ethtool.c index 06c9c12b..9080076c 100644 --- a/src/libnm-core-impl/nm-setting-ethtool.c +++ b/src/libnm-core-impl/nm-setting-ethtool.c @@ -10,6 +10,7 @@ #include "nm-setting-private.h" #include "libnm-base/nm-ethtool-base.h" #include "libnm-base/nm-ethtool-utils-base.h" +#include "libnm-glib-aux/nm-enum-utils.h" /*****************************************************************************/ @@ -121,6 +122,21 @@ nm_ethtool_optname_is_pause(const char *optname) { return optname && nm_ethtool_id_is_pause(nm_ethtool_id_get_by_name(optname)); } +/** + * nm_ethtool_optname_is_fec: + * @optname: (nullable): the option name to check + * + * Checks whether @optname is a valid option name for a fec setting. + * + * Returns: %TRUE, if @optname is valid + * + * Since: 1.52 + */ +gboolean +nm_ethtool_optname_is_fec(const char *optname) +{ + return optname && nm_ethtool_id_is_fec(nm_ethtool_id_get_by_name(optname)); +} /*****************************************************************************/ @@ -309,6 +325,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) NMTernary pause_autoneg = NM_TERNARY_DEFAULT; NMTernary pause_tx = NM_TERNARY_DEFAULT; NMTernary pause_rx = NM_TERNARY_DEFAULT; + guint32 fec_mode = 0; len = _nm_setting_option_get_all(setting, &optnames, &variants); @@ -356,6 +373,8 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) pause_rx = g_variant_get_boolean(variant); else if (NM_IN_SET(ethtool_id, NM_ETHTOOL_ID_PAUSE_TX)) pause_tx = g_variant_get_boolean(variant); + else if (NM_IN_SET(ethtool_id, NM_ETHTOOL_ID_FEC_MODE)) + fec_mode = g_variant_get_uint32(variant); } if (pause_rx != NM_TERNARY_DEFAULT || pause_tx != NM_TERNARY_DEFAULT) { @@ -372,6 +391,32 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) } } + if (fec_mode == NM_SETTING_ETHTOOL_FEC_MODE_NONE + || fec_mode >= (_NM_SETTING_ETHTOOL_FEC_MODE_LAST << 1)) { + gs_free const char *cur_fec_mode = NULL; + gs_free const char **valid_all = NULL; + gs_free const char *valid_str = NULL; + + cur_fec_mode = _nm_utils_enum_to_str_full(nm_setting_ethtool_fec_mode_get_type(), + (int) (fec_mode & INT_MAX), + ", ", + NULL); + valid_all = nm_utils_enum_get_values(nm_setting_ethtool_fec_mode_get_type(), 0, G_MAXUINT); + valid_str = g_strjoinv(",", (char **) valid_all); + + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is not valid FEC modes, valid modes are combinations of %s"), + cur_fec_mode, + valid_str); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_ETHTOOL_SETTING_NAME, + NM_ETHTOOL_OPTNAME_FEC_MODE); + return FALSE; + } + return TRUE; } diff --git a/src/libnm-core-impl/nm-setting-gsm.c b/src/libnm-core-impl/nm-setting-gsm.c index 632b0ccc..02e0e236 100644 --- a/src/libnm-core-impl/nm-setting-gsm.c +++ b/src/libnm-core-impl/nm-setting-gsm.c @@ -38,7 +38,16 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_AUTO_CONFIG, PROP_SIM_OPERATOR_ID, PROP_MTU, PROP_INITIAL_EPS_CONFIG, - PROP_INITIAL_EPS_APN, ); + PROP_INITIAL_EPS_APN, + PROP_INITIAL_EPS_USERNAME, + PROP_INITIAL_EPS_PASSWORD, + PROP_INITIAL_EPS_PASSWORD_FLAGS, + PROP_INITIAL_EPS_NOAUTH, + PROP_INITIAL_EPS_REFUSE_EAP, + PROP_INITIAL_EPS_REFUSE_PAP, + PROP_INITIAL_EPS_REFUSE_CHAP, + PROP_INITIAL_EPS_REFUSE_MSCHAP, + PROP_INITIAL_EPS_REFUSE_MSCHAPV2, ); typedef struct { char *number; @@ -51,7 +60,16 @@ typedef struct { char *network_id; char *pin; char *initial_eps_apn; + char *initial_eps_username; + char *initial_eps_password; + bool initial_eps_noauth; + bool initial_eps_refuse_eap; + bool initial_eps_refuse_pap; + bool initial_eps_refuse_chap; + bool initial_eps_refuse_mschap; + bool initial_eps_refuse_mschapv2; guint password_flags; + guint initial_eps_password_flags; guint pin_flags; guint32 mtu; bool auto_config; @@ -319,6 +337,134 @@ nm_setting_gsm_get_initial_eps_apn(NMSettingGsm *setting) return NM_SETTING_GSM_GET_PRIVATE(setting)->initial_eps_apn; } +/** + * nm_setting_gsm_get_initial_eps_username: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:initial-eps-bearer-username property of the setting + * + * Since: 1.52 + **/ +const char * +nm_setting_gsm_get_initial_eps_username(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->initial_eps_username; +} + +/** + * nm_setting_gsm_get_initial_eps_password: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingGsm:initial-eps-bearer-password property of the setting + * + * Since: 1.52 + **/ +const char * +nm_setting_gsm_get_initial_eps_password(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), NULL); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->initial_eps_password; +} + +/** + * nm_setting_gsm_get_initial_eps_noauth: + * @setting: the #NMSettingGsm + * + * Returns: For LTE modems, the #NMSettingGsm:initial-eps-noauth property of the setting + * + * Since: 1.52 + **/ +gboolean +nm_setting_gsm_get_initial_eps_noauth(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), FALSE); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->initial_eps_noauth; +} + +/** + * nm_setting_gsm_get_initial_eps_refuse_eap: + * @setting: the #NMSettingGsm + * + * Returns: For LTE modems, the #NMSettingGsm:initial-eps-refuse-eap property of the setting + * + * Since: 1.52 + **/ +gboolean +nm_setting_gsm_get_initial_eps_refuse_eap(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), FALSE); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->initial_eps_refuse_eap; +} + +/** + * nm_setting_gsm_get_initial_eps_refuse_pap: + * @setting: the #NMSettingGsm + * + * Returns: For LTE modems, the #NMSettingGsm:initial-eps-refuse-pap property of the setting + * + * Since: 1.52 + **/ +gboolean +nm_setting_gsm_get_initial_eps_refuse_pap(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), FALSE); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->initial_eps_refuse_pap; +} + +/** + * nm_setting_gsm_get_initial_eps_refuse_chap: + * @setting: the #NMSettingGsm + * + * Returns: For LTE modems, the #NMSettingGsm:initial-eps-refuse-chap property of the setting + * + * Since: 1.52 + **/ +gboolean +nm_setting_gsm_get_initial_eps_refuse_chap(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), FALSE); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->initial_eps_refuse_chap; +} + +/** + * nm_setting_gsm_get_initial_eps_refuse_mschap: + * @setting: the #NMSettingGsm + * + * Returns: For LTE modems, the #NMSettingGsm:initial-eps-refuse-mschap property of the setting + * + * Since: 1.52 + **/ +gboolean +nm_setting_gsm_get_initial_eps_refuse_mschap(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), FALSE); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->initial_eps_refuse_mschap; +} + +/** + * nm_setting_gsm_get_initial_eps_refuse_mschapv2: + * @setting: the #NMSettingGsm + * + * Returns: For LTE modems, the #NMSettingGsm:initial-eps-refuse-mschapv2 property of the setting + * + * Since: 1.52 + **/ +gboolean +nm_setting_gsm_get_initial_eps_refuse_mschapv2(NMSettingGsm *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_GSM(setting), FALSE); + + return NM_SETTING_GSM_GET_PRIVATE(setting)->initial_eps_refuse_mschapv2; +} + static gboolean _verify_apn(const char *apn, gboolean allow_empty, const char *property_name, GError **error) { @@ -847,6 +993,162 @@ nm_setting_gsm_class_init(NMSettingGsmClass *klass) initial_eps_apn, .direct_string_allow_empty = TRUE); + /** + * NMSettingGsm:initial-eps-bearer-username: + * + * For LTE modems, this sets the username for the initial EPS bearer that is set + * up when attaching to the network. Setting this parameter implies + * initial-eps-bearer-configure to be TRUE. + * + * Since: 1.52 + **/ + _nm_setting_property_define_direct_string(properties_override, + obj_properties, + NM_SETTING_GSM_INITIAL_EPS_BEARER_USERNAME, + PROP_INITIAL_EPS_USERNAME, + NM_SETTING_PARAM_NONE, + NMSettingGsmPrivate, + initial_eps_username, + .direct_string_allow_empty = TRUE); + + /** + * NMSettingGsm:initial-eps-bearer-password: + * + * For LTE modems, this sets the password for the initial EPS bearer that is set + * up when attaching to the network. Setting this parameter implies + * initial-eps-bearer-configure to be TRUE. + * + * Since: 1.52 + **/ + _nm_setting_property_define_direct_string(properties_override, + obj_properties, + NM_SETTING_GSM_INITIAL_EPS_BEARER_PASSWORD, + PROP_INITIAL_EPS_PASSWORD, + NM_SETTING_PARAM_SECRET, + NMSettingGsmPrivate, + initial_eps_password, + .direct_string_allow_empty = TRUE); + + /** + * NMSettingGsm:initial-eps-bearer-password-flags: + * + * Flags indicating how to handle the #NMSettingGsm:initial-eps-bearer-password property. + * + * Since: 1.52 + **/ + _nm_setting_property_define_direct_secret_flags( + properties_override, + obj_properties, + NM_SETTING_GSM_INITIAL_EPS_BEARER_PASSWORD_FLAGS, + PROP_INITIAL_EPS_PASSWORD_FLAGS, + NMSettingGsmPrivate, + initial_eps_password_flags); + + /** + * NMSettingGsm:initial-eps-bearer-noauth: + * + * For LTE modems, this sets NOAUTH authentication method for the initial EPS bearer that is set + * up when attaching to the network. + * If %TRUE, do not require the other side to authenticate itself to the client. + * If %FALSE, require authentication from the remote side. In almost all cases, + * this should be %TRUE. + * + * Since: 1.52 + **/ + _nm_setting_property_define_direct_boolean(properties_override, + obj_properties, + NM_SETTING_GSM_INITIAL_EPS_BEARER_NOAUTH, + PROP_INITIAL_EPS_NOAUTH, + TRUE, + NM_SETTING_PARAM_NONE, + NMSettingGsmPrivate, + initial_eps_noauth); + + /** + * NMSettingGsm:initial-eps-bearer-refuse-eap: + * + * For LTE modems, this disables EAP authentication method for the initial EPS bearer that is set + * up when attaching to the network. + * + * Since: 1.52 + **/ + _nm_setting_property_define_direct_boolean(properties_override, + obj_properties, + NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_EAP, + PROP_INITIAL_EPS_REFUSE_EAP, + FALSE, + NM_SETTING_PARAM_NONE, + NMSettingGsmPrivate, + initial_eps_refuse_eap); + + /** + * NMSettingGsm:initial-eps-bearer-refuse-pap: + * + * For LTE modems, this disables PAP authentication method for the initial EPS bearer that is set + * up when attaching to the network. + * + * Since: 1.52 + **/ + _nm_setting_property_define_direct_boolean(properties_override, + obj_properties, + NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_PAP, + PROP_INITIAL_EPS_REFUSE_PAP, + FALSE, + NM_SETTING_PARAM_NONE, + NMSettingGsmPrivate, + initial_eps_refuse_pap); + + /** + * NMSettingGsm:initial-eps-bearer-refuse-chap: + * + * For LTE modems, this disables CHAP authentication method for the initial EPS bearer that is set + * up when attaching to the network. + * + * Since: 1.52 + **/ + _nm_setting_property_define_direct_boolean(properties_override, + obj_properties, + NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_CHAP, + PROP_INITIAL_EPS_REFUSE_CHAP, + FALSE, + NM_SETTING_PARAM_NONE, + NMSettingGsmPrivate, + initial_eps_refuse_chap); + + /** + * NMSettingGsm:initial-eps-bearer-refuse-mschap: + * + * For LTE modems, this disables MSCHAP authentication method for the initial EPS bearer that is set + * up when attaching to the network. + * + * Since: 1.52 + **/ + _nm_setting_property_define_direct_boolean(properties_override, + obj_properties, + NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_MSCHAP, + PROP_INITIAL_EPS_REFUSE_MSCHAP, + FALSE, + NM_SETTING_PARAM_NONE, + NMSettingGsmPrivate, + initial_eps_refuse_mschap); + + /** + * NMSettingGsm:initial-eps-bearer-refuse-mschapv2: + * + * For LTE modems, this disables MSCHAPV2 authentication method for the initial EPS bearer that is set + * up when attaching to the network. + * + * Since: 1.52 + **/ + _nm_setting_property_define_direct_boolean(properties_override, + obj_properties, + NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_MSCHAPV2, + PROP_INITIAL_EPS_REFUSE_MSCHAPV2, + FALSE, + NM_SETTING_PARAM_NONE, + NMSettingGsmPrivate, + initial_eps_refuse_mschapv2); + /* Ignore incoming deprecated properties */ _nm_properties_override_dbus(properties_override, "allowed-bands", diff --git a/src/libnm-core-impl/nm-setting-ip-config.c b/src/libnm-core-impl/nm-setting-ip-config.c index e79f25a8..1ec97029 100644 --- a/src/libnm-core-impl/nm-setting-ip-config.c +++ b/src/libnm-core-impl/nm-setting-ip-config.c @@ -175,7 +175,7 @@ nm_ip_address_new(int family, const char *addr, guint prefix, GError **error) return NULL; address = g_slice_new(NMIPAddress); - *address = (NMIPAddress){ + *address = (NMIPAddress) { .refcount = 1, .family = family, .address = canonicalize_ip_binary(family, &addr_bin, FALSE), @@ -210,7 +210,7 @@ nm_ip_address_new_binary(int family, gconstpointer addr, guint prefix, GError ** return NULL; address = g_slice_new(NMIPAddress); - *address = (NMIPAddress){ + *address = (NMIPAddress) { .refcount = 1, .family = family, .address = nm_inet_ntop_dup(family, addr), @@ -637,7 +637,7 @@ nm_ip_route_new(int family, return NULL; route = g_slice_new(NMIPRoute); - *route = (NMIPRoute){ + *route = (NMIPRoute) { .refcount = 1, .family = family, .dest = canonicalize_ip_binary(family, &dest_bin, FALSE), @@ -683,7 +683,7 @@ nm_ip_route_new_binary(int family, return NULL; route = g_slice_new0(NMIPRoute); - *route = (NMIPRoute){ + *route = (NMIPRoute) { .refcount = 1, .family = family, .dest = canonicalize_ip_binary(family, dest, FALSE), @@ -1655,7 +1655,7 @@ nm_ip_routing_rule_new(int addr_family) g_return_val_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6), NULL); self = g_slice_new(NMIPRoutingRule); - *self = (NMIPRoutingRule){ + *self = (NMIPRoutingRule) { .ref_count = 1, .is_v4 = (addr_family == AF_INET), .action = FR_ACT_TO_TBL, @@ -1685,7 +1685,7 @@ nm_ip_routing_rule_new_clone(const NMIPRoutingRule *rule) g_return_val_if_fail(NM_IS_IP_ROUTING_RULE(rule, TRUE), NULL); self = g_slice_new(NMIPRoutingRule); - *self = (NMIPRoutingRule){ + *self = (NMIPRoutingRule) { .ref_count = 1, .sealed = FALSE, .is_v4 = rule->is_v4, @@ -3996,6 +3996,7 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMSettingIPConfig, PROP_DHCP_DSCP, PROP_DHCP_HOSTNAME_FLAGS, PROP_DHCP_SEND_HOSTNAME, + PROP_DHCP_SEND_HOSTNAME_V2, PROP_NEVER_DEFAULT, PROP_MAY_FAIL, PROP_DAD_TIMEOUT, @@ -4005,7 +4006,10 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMSettingIPConfig, PROP_DHCP_REJECT_SERVERS, PROP_AUTO_ROUTE_EXT_GW, PROP_REPLACE_LOCAL_RULE, - PROP_DHCP_SEND_RELEASE, ); + PROP_DHCP_SEND_RELEASE, + PROP_ROUTED_DNS, + PROP_SHARED_DHCP_RANGE, + PROP_SHARED_DHCP_LEASE_TIME, ); G_DEFINE_ABSTRACT_TYPE(NMSettingIPConfig, nm_setting_ip_config, NM_TYPE_SETTING) @@ -4091,7 +4095,7 @@ _ip_config_add_dns(NMSettingIPConfig *setting, const char *dns) priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); - s = nm_utils_dnsname_normalize(NM_SETTING_IP_CONFIG_GET_ADDR_FAMILY(setting), dns, &s_free); + s = nm_dns_uri_normalize(NM_SETTING_IP_CONFIG_GET_ADDR_FAMILY(setting), dns, &s_free); if (!s) s = dns; @@ -4182,7 +4186,7 @@ nm_setting_ip_config_remove_dns_by_value(NMSettingIPConfig *setting, const char gs_free char *s_free = NULL; const char *s; - s = nm_utils_dnsname_normalize(NM_SETTING_IP_CONFIG_GET_ADDR_FAMILY(setting), dns, &s_free); + s = nm_dns_uri_normalize(NM_SETTING_IP_CONFIG_GET_ADDR_FAMILY(setting), dns, &s_free); if (s && !nm_streq(dns, s)) idx = nm_strv_ptrarray_find_first(priv->dns, dns); } @@ -5193,6 +5197,8 @@ nm_setting_ip_config_get_dhcp_hostname(NMSettingIPConfig *setting) * Returns: %TRUE if NetworkManager should send the machine hostname to the * DHCP server when requesting addresses to allow the server to automatically * update DNS information for this machine. + * + * Deprecated: 1.52. Use nm_setting_ip_config_get_dhcp_send_hostname_v2() instead. **/ gboolean nm_setting_ip_config_get_dhcp_send_hostname(NMSettingIPConfig *setting) @@ -5203,6 +5209,25 @@ nm_setting_ip_config_get_dhcp_send_hostname(NMSettingIPConfig *setting) } /** + * nm_setting_ip_config_get_dhcp_send_hostname_v2: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:dhcp-send-hostname-v2 + * property. + * + * Returns: the #NMSettingIPConfig:dhcp-send-hostname-v2 property of the setting + * + * Since: 1.52 + **/ +NMTernary +nm_setting_ip_config_get_dhcp_send_hostname_v2(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NM_TERNARY_DEFAULT); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dhcp_send_hostname_v2; +} + +/** * nm_setting_ip_config_get_dhcp_dscp: * @setting: the #NMSettingIPConfig * @@ -5480,6 +5505,60 @@ nm_setting_ip_config_get_dhcp_send_release(NMSettingIPConfig *setting) return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->dhcp_send_release; } +/** + * nm_setting_ip_config_get_routed_dns: + * @setting: the #NMSettingIPConfig + * + * Returns: the #NMSettingIPConfig:routed-dns property of the setting + * + * Since: 1.52 + **/ +NMSettingIPConfigRoutedDns +nm_setting_ip_config_get_routed_dns(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NM_SETTING_IP_CONFIG_ROUTED_DNS_DEFAULT); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->routed_dns; +} + +/** + * nm_setting_ip_config_get_shared_dhcp_range: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:shared-dhcp-range + * property. + * + * Returns: the configured DHCP server range + * + * Since: 1.52 + **/ +const char * +nm_setting_ip_config_get_shared_dhcp_range(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NULL); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->shared_dhcp_range; +} + +/** + * nm_setting_ip_config_get_shared_dhcp_lease_time: + * @setting: the #NMSettingIPConfig + * + * Returns the value contained in the #NMSettingIPConfig:shared-dhcp-lease-time + * property. + * + * Returns: the configured DHCP server lease time + * + * Since: 1.52 + **/ +int +nm_setting_ip_config_get_shared_dhcp_lease_time(NMSettingIPConfig *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), 0); + + return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->shared_dhcp_lease_time; +} + static gboolean verify_label(const char *label) { @@ -5536,11 +5615,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) for (i = 0; i < priv->dns->len; i++) { const char *dns = priv->dns->pdata[i]; - if (!nm_utils_dnsname_parse(NM_SETTING_IP_CONFIG_GET_ADDR_FAMILY(setting), - dns, - NULL, - NULL, - NULL)) { + if (!nm_dns_uri_parse(NM_SETTING_IP_CONFIG_GET_ADDR_FAMILY(setting), dns, NULL)) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, @@ -5776,6 +5851,26 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } + /* Validate DHCP range served in the shared mode */ + if (priv->shared_dhcp_range + && !nm_utils_validate_shared_dhcp_range(priv->shared_dhcp_range, priv->addresses, error)) { + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_SHARED_DHCP_RANGE); + return FALSE; + } + + /* Validate DHCP lease time */ + if (priv->shared_dhcp_lease_time + && !nm_utils_validate_shared_dhcp_lease_time(priv->shared_dhcp_lease_time, error)) { + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_SHARED_DHCP_LEASE_TIME); + return FALSE; + } + /* Normalizable errors */ if (priv->gateway && priv->never_default) { g_set_error(error, @@ -5790,6 +5885,20 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; } + if (priv->dhcp_send_hostname_v2 != NM_TERNARY_DEFAULT + && priv->dhcp_send_hostname != priv->dhcp_send_hostname_v2) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("the value is inconsistent with '%s'"), + NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME_V2); + g_prefix_error(error, + "%s.%s: ", + nm_setting_get_name(setting), + NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + return TRUE; } @@ -6133,6 +6242,14 @@ _nm_sett_info_property_override_create_array_ip_config(int addr_family) _nm_properties_override_gobj( properties_override, + obj_properties[PROP_DHCP_SEND_HOSTNAME_V2], + &nm_sett_info_propert_type_direct_enum, + .direct_offset = + NM_STRUCT_OFFSET_ENSURE_TYPE(int, NMSettingIPConfigPrivate, dhcp_send_hostname_v2), + .direct_data.enum_gtype = NM_TYPE_TERNARY); + + _nm_properties_override_gobj( + properties_override, obj_properties[PROP_DHCP_HOSTNAME_FLAGS], &nm_sett_info_propert_type_direct_uint32, .direct_offset = @@ -6198,6 +6315,28 @@ _nm_sett_info_property_override_create_array_ip_config(int addr_family) NMSettingIPConfigPrivate, dhcp_reject_servers)); + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_ROUTED_DNS], + &nm_sett_info_propert_type_direct_enum, + .direct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE(int, NMSettingIPConfigPrivate, routed_dns), + .direct_data.enum_gtype = NM_TYPE_SETTING_IP_CONFIG_ROUTED_DNS); + + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_SHARED_DHCP_RANGE], + &nm_sett_info_propert_type_direct_string, + .direct_offset = + NM_STRUCT_OFFSET_ENSURE_TYPE(char *, NMSettingIPConfigPrivate, shared_dhcp_range), + .direct_string_allow_empty = TRUE); + + _nm_properties_override_gobj( + properties_override, + obj_properties[PROP_SHARED_DHCP_LEASE_TIME], + &nm_sett_info_propert_type_direct_int32, + .direct_offset = + NM_STRUCT_OFFSET_ENSURE_TYPE(gint32, NMSettingIPConfigPrivate, shared_dhcp_lease_time)); + return properties_override; } @@ -6367,11 +6506,16 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) /** * NMSettingIPConfig:dns: * - * Array of IP addresses of DNS servers. + * Array of DNS servers. + * + * Each server can be specified either as a plain IP address (optionally followed + * by a "#" and the SNI server name for DNS over TLS) or with a URI syntax. + * + * When it is specified as an URI, the following forms are supported: + * dns+udp://ADDRESS[:PORT], dns+tls://ADDRESS[:PORT][#SERVERNAME] . * - * For DoT (DNS over TLS), the SNI server name can be specified by appending - * "#example.com" to the IP address of the DNS server. This currently only has - * effect when using systemd-resolved. + * When using the URI syntax, IPv6 addresses must be enclosed in square + * brackets ('[', ']'). **/ obj_properties[PROP_DNS] = g_param_spec_boxed(NM_SETTING_IP_CONFIG_DNS, @@ -6662,12 +6806,21 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) /** * NMSettingIPConfig:dhcp-send-hostname: * - * If %TRUE, a hostname is sent to the DHCP server when acquiring a lease. - * Some DHCP servers use this hostname to update DNS databases, essentially - * providing a static hostname for the computer. If the - * #NMSettingIPConfig:dhcp-hostname property is %NULL and this property is - * %TRUE, the current persistent hostname of the computer is sent. + * Since 1.52 this property is deprecated and is only used as fallback value + * for #NMSettingIPConfig:dhcp-send-hostname-v2 if it's set to 'default'. + * This is only done to avoid breaking existing configurations, the new + * property should be used from now on. + * + * Deprecated: 1.52: use the new version of dhcp-send-hostname instead. **/ + /* ---nmcli--- + * property: dhcp-send-hostname + * rename: dhcp-send-hostname-deprecated + * description: Since 1.52 this property is deprecated and is only used as fallback value + * for dhcp-send-hostname if it's set to 'default'. This is only done to avoid + * breaking existing configurations, the new property should be used from now on. + * ---end--- + */ obj_properties[PROP_DHCP_SEND_HOSTNAME] = g_param_spec_boolean(NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, "", @@ -6946,5 +7099,111 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) NM_TERNARY_DEFAULT, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + /** + * NMSettingIPConfig:routed-dns: + * + * Whether to add routes for DNS servers. When enabled, NetworkManager adds a route + * for each DNS server that is associated with this connection either statically + * (defined in the connection profile) or dynamically (for example, retrieved via + * DHCP). The route guarantees that the DNS server is reached via this interface. When + * set to %NM_SETTING_IP_CONFIG_ROUTED_DNS_DEFAULT, the value from global + * configuration is used; if no global default is defined, this feature is disabled. + * + * Since: 1.52 + */ + obj_properties[PROP_ROUTED_DNS] = + g_param_spec_int(NM_SETTING_IP_CONFIG_ROUTED_DNS, + "", + "", + NM_SETTING_IP_CONFIG_ROUTED_DNS_DEFAULT, + NM_SETTING_IP_CONFIG_ROUTED_DNS_YES, + NM_SETTING_IP_CONFIG_ROUTED_DNS_DEFAULT, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:dhcp-send-hostname-v2: + * + * If %TRUE, a hostname is sent to the DHCP server when acquiring a lease. + * Some DHCP servers use this hostname to update DNS databases, essentially + * providing a static hostname for the computer. If the + * #NMSettingIPConfig:dhcp-hostname property is %NULL and this property is + * %TRUE, the current persistent hostname of the computer is sent. + * + * The default value is %NM_TERNARY_DEFAULT. In this case the global value + * from NetworkManager configuration is looked up. If it's not set, the value + * from #NMSettingIPConfig:dhcp-send-hostname, which defaults to %TRUE, is + * used for backwards compatibility. In the future this will change and, in + * absence of a global default, it will always fallback to %TRUE. + * + * Since: 1.52 + **/ + /* ---nmcli--- + * property: dhcp-send-hostname-v2 + * rename: dhcp-send-hostname + * description: If %TRUE, a hostname is sent to the DHCP server when acquiring a lease. + * Some DHCP servers use this hostname to update DNS databases, essentially + * providing a static hostname for the computer. If the dhcp-hostname + * property is %NULL and this property is %TRUE, the current persistent + * hostname of the computer is sent. + * + * The default value is %NM_TERNARY_DEFAULT. In this case the global value + * from NetworkManager configuration is looked up. If it's not set, the value + * from dhcp-send-hostname-deprecated, which defaults to %TRUE, is + * used for backwards compatibility. In the future this will change and, in + * absence of a global default, it will always fallback to %TRUE. + * ---end--- + */ + obj_properties[PROP_DHCP_SEND_HOSTNAME_V2] = + g_param_spec_int(NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME_V2, + "", + "", + G_MININT, + G_MAXINT, + NM_TERNARY_DEFAULT, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:shared-dhcp-range: + * + * This option allows you to specify a custom DHCP range for the shared connection + * method. The value is expected to be in `<START_ADDRESS>,<END_ADDRESS>` format. + * The range should be part of network set by ipv4.address option and it should + * not contain network address or broadcast address. If this option is not specified, + * the DHCP range will be automatically determined based on the interface address. + * The range will be selected to be adjacent to the interface address, either before + * or after it, with the larger possible range being preferred. The range will be + * adjusted to fill the available address space, except for networks with a prefix + * length greater than 24, which will be treated as if they have a prefix length of 24. + * + * Since: 1.52 + */ + obj_properties[PROP_SHARED_DHCP_RANGE] = + g_param_spec_string(NM_SETTING_IP_CONFIG_SHARED_DHCP_RANGE, + "", + "", + NULL, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * NMSettingIPConfig:shared-dhcp-lease-time: + * + * This option allows you to specify a custom DHCP lease time for the shared connection + * method in seconds. The value should be either a number between 120 and 31536000 (one year) + * If this option is not specified, 3600 (one hour) is used. + * + * Special values are 0 for default value of 1 hour and 2147483647 (MAXINT32) for infinite lease time. + * + * Since: 1.52 + */ + obj_properties[PROP_SHARED_DHCP_LEASE_TIME] = + g_param_spec_int(NM_SETTING_IP_CONFIG_SHARED_DHCP_LEASE_TIME, + "", + "", + 0, + G_MAXINT32, + 0, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | NM_SETTING_PARAM_FUZZY_IGNORE + | G_PARAM_STATIC_STRINGS); + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); } diff --git a/src/libnm-core-impl/nm-setting-ip4-config.c b/src/libnm-core-impl/nm-setting-ip4-config.c index 6112137f..a4fccc6d 100644 --- a/src/libnm-core-impl/nm-setting-ip4-config.c +++ b/src/libnm-core-impl/nm-setting-ip4-config.c @@ -39,7 +39,8 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_DHCP_CLIENT_ID, PROP_DHCP_FQDN, PROP_DHCP_VENDOR_CLASS_IDENTIFIER, - PROP_LINK_LOCAL, ); + PROP_LINK_LOCAL, + PROP_DHCP_IPV6_ONLY_PREFERRED, ); typedef struct { NMSettingIPConfigPrivate parent; @@ -48,6 +49,7 @@ typedef struct { char *dhcp_fqdn; char *dhcp_vendor_class_identifier; gint32 link_local; + gint32 dhcp_ipv6_only_preferred; } NMSettingIP4ConfigPrivate; /** @@ -146,6 +148,26 @@ nm_setting_ip4_config_get_link_local(NMSettingIP4Config *setting) return NM_SETTING_IP4_CONFIG_GET_PRIVATE(setting)->link_local; } +/** + * nm_setting_ip4_config_get_dhcp_ipv6_only_preferred: + * @setting: the #NMSettingIP4Config + * + * Returns the value in the #NMSettingIP4Config:dhcp-ipv6-only-preferred + * property. + * + * Returns: the DHCP IPv6-only preferred property value + * + * Since: 1.52 + **/ +NMSettingIP4DhcpIpv6OnlyPreferred +nm_setting_ip4_config_get_dhcp_ipv6_only_preferred(NMSettingIP4Config *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IP4_CONFIG(setting), + NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_DEFAULT); + + return NM_SETTING_IP4_CONFIG_GET_PRIVATE(setting)->dhcp_ipv6_only_preferred; +} + static gboolean verify(NMSetting *setting, NMConnection *connection, GError **error) { @@ -241,7 +263,8 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) NM_SETTING_IP4_LL_AUTO, NM_SETTING_IP4_LL_DEFAULT, NM_SETTING_IP4_LL_DISABLED, - NM_SETTING_IP4_LL_ENABLED)) { + NM_SETTING_IP4_LL_ENABLED, + NM_SETTING_IP4_LL_FALLBACK)) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, @@ -252,7 +275,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) NM_SETTING_IP4_CONFIG_LINK_LOCAL); return FALSE; } - if (priv->link_local == NM_SETTING_IP4_LL_ENABLED + if (NM_IN_SET(priv->link_local, NM_SETTING_IP4_LL_ENABLED, NM_SETTING_IP4_LL_FALLBACK) && nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) { g_set_error_literal(error, NM_CONNECTION_ERROR, @@ -1028,6 +1051,8 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) * When set to "default", it honors the global connection default, before * falling back to "auto". Note that if "ipv4.method" is "disabled", then * link local addressing is always disabled too. The default is "default". + * Since 1.52, when set to "fallback", a link-local address is obtained + * if no other IPv4 address is set. * * Since: 1.40 */ @@ -1325,6 +1350,38 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) * ---end--- */ + /** + * NMSettingIP4Config:dhcp-ipv6-only-preferred + * + * Controls the "IPv6-Only Preferred" DHCPv4 option (RFC 8925). + * + * When set to %NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_YES, the host adds the + * option to the parameter request list; if the DHCP server sends the option back, + * the host stops the DHCP client for the time interval specified in the option. + * + * Enable this feature if the host supports an IPv6-only mode, i.e. either all + * applications are IPv6-only capable or there is a form of 464XLAT deployed. + * + * When set to %NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_DEFAULT, the actual value + * is looked up in the global configuration; if not specified, it defaults to + * %NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_NO. + * + * If the connection has IPv6 method set to "disabled", this property does not + * have effect and the "IPv6-Only Preferred" option is always disabled. + * + * Since: 1.52 + */ + _nm_setting_property_define_direct_enum(properties_override, + obj_properties, + NM_SETTING_IP4_CONFIG_DHCP_IPV6_ONLY_PREFERRED, + PROP_DHCP_IPV6_ONLY_PREFERRED, + NM_TYPE_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED, + NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_DEFAULT, + NM_SETTING_PARAM_NONE, + NULL, + NMSettingIP4ConfigPrivate, + dhcp_ipv6_only_preferred); + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); _nm_setting_class_commit(setting_class, diff --git a/src/libnm-core-impl/nm-setting-ip6-config.c b/src/libnm-core-impl/nm-setting-ip6-config.c index 32fb295f..c68be991 100644 --- a/src/libnm-core-impl/nm-setting-ip6-config.c +++ b/src/libnm-core-impl/nm-setting-ip6-config.c @@ -440,6 +440,30 @@ verify(NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } + if (nm_setting_ip_config_get_shared_dhcp_range(s_ip)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Shared DHCP range is not supported for IPv6")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_SHARED_DHCP_RANGE); + return FALSE; + } + + if (nm_setting_ip_config_get_shared_dhcp_lease_time(s_ip)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("Shared DHCP lease time is not supported for IPv6")); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_SETTING_IP_CONFIG_SHARED_DHCP_LEASE_TIME); + return FALSE; + } + /* Failures from here on, are NORMALIZABLE_ERROR... */ if (token_needs_normalization) { diff --git a/src/libnm-core-impl/nm-setting-ipvlan.c b/src/libnm-core-impl/nm-setting-ipvlan.c new file mode 100644 index 00000000..fafa37b6 --- /dev/null +++ b/src/libnm-core-impl/nm-setting-ipvlan.c @@ -0,0 +1,290 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024 Red Hat, Inc. + */ + +#include "libnm-core-impl/nm-default-libnm-core.h" + +#include "nm-setting-ipvlan.h" + +#include "nm-connection-private.h" +#include "nm-utils.h" +#include "nm-utils-private.h" + +/** + * SECTION:nm-setting-ipvlan + * @short_description: Describes connection properties for IPVLAN interfaces + * + * The #NMSettingIpvlan object is a #NMSetting subclass that describes properties + * necessary for connection to IPVLAN interfaces. + **/ + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PARENT, PROP_MODE, PROP_PRIVATE, PROP_VEPA, ); + +typedef struct { + char *parent; + guint32 mode; + bool private_flag; + bool vepa; +} NMSettingIpvlanPrivate; + +/** + * NMSettingIpvlan: + * + * IPVLAN Settings + */ +struct _NMSettingIpvlan { + NMSetting parent; + NMSettingIpvlanPrivate _priv; +}; + +struct _NMSettingIpvlanClass { + NMSettingClass parent; +}; + +G_DEFINE_TYPE(NMSettingIpvlan, nm_setting_ipvlan, NM_TYPE_SETTING) + +#define NM_SETTING_IPVLAN_GET_PRIVATE(o) \ + _NM_GET_PRIVATE(o, NMSettingIpvlan, NM_IS_SETTING_IPVLAN, NMSetting) + +/*****************************************************************************/ + +/** + * nm_setting_ipvlan_get_parent: + * @setting: the #NMSettingIpvlan + * + * Returns: the #NMSettingIpvlan:parent property of the setting + * + * Since: 1.52 + **/ +const char * +nm_setting_ipvlan_get_parent(NMSettingIpvlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IPVLAN(setting), NULL); + + return NM_SETTING_IPVLAN_GET_PRIVATE(setting)->parent; +} + +/** + * nm_setting_ipvlan_get_mode: + * @setting: the #NMSettingIpvlan + * + * Returns: the #NMSettingIpvlan:mode property of the setting + * + * Since: 1.52 + **/ +NMSettingIpvlanMode +nm_setting_ipvlan_get_mode(NMSettingIpvlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IPVLAN(setting), NM_SETTING_IPVLAN_MODE_UNKNOWN); + + return NM_SETTING_IPVLAN_GET_PRIVATE(setting)->mode; +} + +/** + * nm_setting_ipvlan_get_private: + * @setting: the #NMSettingIpvlan + * + * Returns: the #NMSettingIpvlan:private property of the setting + * + * Since: 1.52 + **/ +gboolean +nm_setting_ipvlan_get_private(NMSettingIpvlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IPVLAN(setting), FALSE); + + return NM_SETTING_IPVLAN_GET_PRIVATE(setting)->private_flag; +} + +/** + * nm_setting_ipvlan_get_vepa: + * @setting: the #NMSettingIpvlan + * + * Returns: the #NMSettingIpvlan:vepa property of the setting + * + * Since: 1.52 + **/ +gboolean +nm_setting_ipvlan_get_vepa(NMSettingIpvlan *setting) +{ + g_return_val_if_fail(NM_IS_SETTING_IPVLAN(setting), FALSE); + + return NM_SETTING_IPVLAN_GET_PRIVATE(setting)->vepa; +} + +/*****************************************************************************/ + +static gboolean +verify(NMSetting *setting, NMConnection *connection, GError **error) +{ + NMSettingIpvlanPrivate *priv = NM_SETTING_IPVLAN_GET_PRIVATE(setting); + NMSettingWired *s_wired = NULL; + + if (connection) + s_wired = nm_connection_get_setting_wired(connection); + + if (priv->parent) { + if (!nm_utils_is_uuid(priv->parent) && !nm_utils_ifname_valid_kernel(priv->parent, NULL)) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' is neither an UUID nor an interface name"), + priv->parent); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IPVLAN_SETTING_NAME, + NM_SETTING_IPVLAN_PARENT); + return FALSE; + } + } else { + /* If parent is NULL, the parent must be specified via NMSettingWired:mac-address. */ + if (connection && (!s_wired || !nm_setting_wired_get_mac_address(s_wired))) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is not specified and neither is '%s:%s'"), + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_MAC_ADDRESS); + g_prefix_error(error, + "%s.%s: ", + NM_SETTING_IPVLAN_SETTING_NAME, + NM_SETTING_IPVLAN_PARENT); + return FALSE; + } + } + + if (priv->private_flag && priv->vepa) { + g_set_error(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("private and VEPA cannot be enabled at the same time")); + g_prefix_error(error, "%s: ", NM_SETTING_IPVLAN_SETTING_NAME); + return FALSE; + } + + if (!_nm_connection_verify_required_interface_name(connection, error)) + return FALSE; + + return TRUE; +} + +/*****************************************************************************/ + +static void +nm_setting_ipvlan_init(NMSettingIpvlan *self) +{} + +/** + * nm_setting_ipvlan_new: + * + * Creates a new #NMSettingIpvlan object with default values. + * + * Returns: (transfer full): the new empty #NMSettingIpvlan object + * + * Since: 1.52 + **/ +NMSetting * +nm_setting_ipvlan_new(void) +{ + return g_object_new(NM_TYPE_SETTING_IPVLAN, NULL); +} + +static void +nm_setting_ipvlan_class_init(NMSettingIpvlanClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + NMSettingClass *setting_class = NM_SETTING_CLASS(klass); + GArray *properties_override = _nm_sett_info_property_override_create_array(); + + object_class->get_property = _nm_setting_property_get_property_direct; + object_class->set_property = _nm_setting_property_set_property_direct; + + setting_class->verify = verify; + + /** + * NMSettingIpvlan:parent: + * + * If given, specifies the parent interface name or parent connection UUID + * from which this IPVLAN interface should be created. If this property is + * not specified, the connection must contain an #NMSettingWired setting + * with a #NMSettingWired:mac-address property. + * + * Since: 1.52 + **/ + _nm_setting_property_define_direct_string(properties_override, + obj_properties, + NM_SETTING_IPVLAN_PARENT, + PROP_PARENT, + NM_SETTING_PARAM_INFERRABLE, + NMSettingIpvlanPrivate, + parent, + .direct_string_allow_empty = TRUE); + + /** + * NMSettingIpvlan:mode: + * + * The IPVLAN mode. Valid values: %NM_SETTING_IPVLAN_MODE_L2, + * %NM_SETTING_IPVLAN_MODE_L3 and %NM_SETTING_IPVLAN_MODE_L3S. + * + * Since: 1.52 + **/ + /* ---nmcli--- + * property: mode + * description: + * The IPVLAN mode. Valid values: l2 (1), l3 (2), l3s (3) + * ---end--- + */ + _nm_setting_property_define_direct_uint32(properties_override, + obj_properties, + NM_SETTING_IPVLAN_MODE, + PROP_MODE, + 0, + G_MAXUINT32, + NM_SETTING_IPVLAN_MODE_UNKNOWN, + NM_SETTING_PARAM_INFERRABLE, + NMSettingIpvlanPrivate, + mode); + + /** + * NMSettingIpvlan:private: + * + * Whether the interface should be put in private mode. + * + * Since: 1.52 + **/ + _nm_setting_property_define_direct_boolean(properties_override, + obj_properties, + NM_SETTING_IPVLAN_PRIVATE, + PROP_PRIVATE, + FALSE, + NM_SETTING_PARAM_INFERRABLE, + NMSettingIpvlanPrivate, + private_flag); + + /** + * NMSettingIpvlan:vepa: + * + * Whether the interface should be put in VEPA mode. + * + * Since: 1.52 + **/ + _nm_setting_property_define_direct_boolean(properties_override, + obj_properties, + NM_SETTING_IPVLAN_VEPA, + PROP_VEPA, + FALSE, + NM_SETTING_PARAM_INFERRABLE, + NMSettingIpvlanPrivate, + vepa); + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, + NM_META_SETTING_TYPE_IPVLAN, + NULL, + properties_override, + G_STRUCT_OFFSET(NMSettingIpvlan, _priv)); +} diff --git a/src/libnm-core-impl/nm-setting-private.h b/src/libnm-core-impl/nm-setting-private.h index da7fdbb7..ba838364 100644 --- a/src/libnm-core-impl/nm-setting-private.h +++ b/src/libnm-core-impl/nm-setting-private.h @@ -186,10 +186,14 @@ typedef struct { char *dhcp_hostname; char *dhcp_iaid; char *dhcp_dscp; + char *shared_dhcp_range; + int shared_dhcp_lease_time; gint64 route_metric; int auto_route_ext_gw; int replace_local_rule; int dhcp_send_release; + int routed_dns; + int dhcp_send_hostname_v2; gint32 required_timeout; gint32 dad_timeout; gint32 dhcp_timeout; @@ -482,7 +486,7 @@ void _nm_setting_class_commit(NMSettingClass *setting_class, &_g; \ }) -#define NM_SETT_INFO_SETT_DETAIL(...) (&((const NMSettInfoSettDetail){__VA_ARGS__})) +#define NM_SETT_INFO_SETT_DETAIL(...) (&((const NMSettInfoSettDetail) {__VA_ARGS__})) #define NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(_dbus_type, ...) {.dbus_type = _dbus_type, __VA_ARGS__} @@ -504,7 +508,7 @@ void _nm_setting_class_commit(NMSettingClass *setting_class, #define NM_SETT_INFO_PROPERT_TYPE_GPROP(_dbus_type, ...) \ NM_SETT_INFO_PROPERT_TYPE(NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT(_dbus_type, __VA_ARGS__)) -#define NM_SETT_INFO_PROPERTY(...) (&((const NMSettInfoProperty){__VA_ARGS__})) +#define NM_SETT_INFO_PROPERTY(...) (&((const NMSettInfoProperty) {__VA_ARGS__})) gboolean _nm_properties_override_assert(const NMSettInfoProperty *prop_info); diff --git a/src/libnm-core-impl/nm-setting-sriov.c b/src/libnm-core-impl/nm-setting-sriov.c index 145c2b14..4dc61d82 100644 --- a/src/libnm-core-impl/nm-setting-sriov.c +++ b/src/libnm-core-impl/nm-setting-sriov.c @@ -103,7 +103,7 @@ nm_sriov_vf_new(guint index) NMSriovVF *vf; vf = g_slice_new(NMSriovVF); - *vf = (NMSriovVF){ + *vf = (NMSriovVF) { .refcount = 1, .index = index, .attributes = g_hash_table_new_full(nm_str_hash, @@ -223,7 +223,7 @@ vf_add_vlan(NMSriovVF *vf, guint vlan_id, guint qos, NMSriovVFVlanProtocol proto VFVlan *vlan; vlan = g_slice_new(VFVlan); - *vlan = (VFVlan){ + *vlan = (VFVlan) { .id = vlan_id, .qos = qos, .protocol = protocol, diff --git a/src/libnm-core-impl/nm-setting-vlan.c b/src/libnm-core-impl/nm-setting-vlan.c index 3a1f0930..5cb2470c 100644 --- a/src/libnm-core-impl/nm-setting-vlan.c +++ b/src/libnm-core-impl/nm-setting-vlan.c @@ -130,7 +130,7 @@ priority_map_new(guint32 from, guint32 to) NMVlanQosMapping *mapping; mapping = g_new(NMVlanQosMapping, 1); - *mapping = (NMVlanQosMapping){ + *mapping = (NMVlanQosMapping) { .from = from, .to = to, }; diff --git a/src/libnm-core-impl/nm-setting-wired.c b/src/libnm-core-impl/nm-setting-wired.c index 2c8562d3..e02c0a06 100644 --- a/src/libnm-core-impl/nm-setting-wired.c +++ b/src/libnm-core-impl/nm-setting-wired.c @@ -810,7 +810,7 @@ nm_setting_wired_add_s390_option(NMSettingWired *setting, const char *key, const &priv->s390_options.arr[dst_idx], (priv->s390_options.len - dst_idx) * sizeof(NMUtilsNamedValue)); } - priv->s390_options.arr[dst_idx] = (NMUtilsNamedValue){ + priv->s390_options.arr[dst_idx] = (NMUtilsNamedValue) { .name = g_strdup(key), .value_str = g_strdup(value), }; @@ -1253,7 +1253,7 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps nm_assert(priv->s390_options.len < priv->s390_options.n_alloc); - priv->s390_options.arr[priv->s390_options.len] = (NMUtilsNamedValue){ + priv->s390_options.arr[priv->s390_options.len] = (NMUtilsNamedValue) { .name = g_strdup(key), .value_str = g_strdup(val), }; diff --git a/src/libnm-core-impl/nm-setting-wireguard.c b/src/libnm-core-impl/nm-setting-wireguard.c index 4f96f742..668af1f6 100644 --- a/src/libnm-core-impl/nm-setting-wireguard.c +++ b/src/libnm-core-impl/nm-setting-wireguard.c @@ -77,7 +77,7 @@ nm_wireguard_peer_new(void) NMWireGuardPeer *self; self = g_slice_new(NMWireGuardPeer); - *self = (NMWireGuardPeer){ + *self = (NMWireGuardPeer) { .refcount = 1, .preshared_key_flags = NM_SETTING_SECRET_FLAG_NOT_REQUIRED, }; @@ -104,7 +104,7 @@ nm_wireguard_peer_new_clone(const NMWireGuardPeer *self, gboolean with_secrets) g_return_val_if_fail(NM_IS_WIREGUARD_PEER(self, TRUE), NULL); new = g_slice_new(NMWireGuardPeer); - *new = (NMWireGuardPeer){ + *new = (NMWireGuardPeer) { .refcount = 1, .public_key = g_strdup(self->public_key), .public_key_valid = self->public_key_valid, @@ -1310,7 +1310,7 @@ _peers_set(NMSettingWireGuardPrivate *priv, if (!pd_same_key) pd_same_key = g_slice_new(PeerData); - *pd_same_key = (PeerData){ + *pd_same_key = (PeerData) { .peer = peer, .public_key = public_key, .idx = priv->peers_arr->len, diff --git a/src/libnm-core-impl/nm-setting.c b/src/libnm-core-impl/nm-setting.c index ed34db76..98424c76 100644 --- a/src/libnm-core-impl/nm-setting.c +++ b/src/libnm-core-impl/nm-setting.c @@ -446,7 +446,7 @@ _nm_setting_class_commit(NMSettingClass *setting_class, const NMSettInfoProperty *property_info = &sett_info->property_infos[j]; if (property_info->param_spec) { - *(lookup_by_iter++) = (NMSettInfoPropertLookupByParamSpec){ + *(lookup_by_iter++) = (NMSettInfoPropertLookupByParamSpec) { .param_spec_as_uint = (uintptr_t) ((gpointer) property_info->param_spec), .property_info = property_info, }; @@ -4346,7 +4346,7 @@ nm_range_new(guint64 start, guint64 end) g_return_val_if_fail(start <= end, NULL); range = g_slice_new(NMRange); - *range = (NMRange){ + *range = (NMRange) { .refcount = 1, .start = start, .end = end, diff --git a/src/libnm-core-impl/nm-team-utils.c b/src/libnm-core-impl/nm-team-utils.c index 6e7f85c7..8e1cdd64 100644 --- a/src/libnm-core-impl/nm-team-utils.c +++ b/src/libnm-core-impl/nm-team-utils.c @@ -692,9 +692,9 @@ _team_setting_has_fields_any_v(const NMTeamSetting *self, return FALSE; } -#define _team_setting_has_fields_any(self, ...) \ - _team_setting_has_fields_any_v((self), \ - ((const NMTeamAttribute[]){__VA_ARGS__}), \ +#define _team_setting_has_fields_any(self, ...) \ + _team_setting_has_fields_any_v((self), \ + ((const NMTeamAttribute[]) {__VA_ARGS__}), \ NM_NARG(__VA_ARGS__)) static void diff --git a/src/libnm-core-impl/nm-utils-private.h b/src/libnm-core-impl/nm-utils-private.h index 1521c0f9..da442511 100644 --- a/src/libnm-core-impl/nm-utils-private.h +++ b/src/libnm-core-impl/nm-utils-private.h @@ -14,7 +14,7 @@ #include "nm-setting-ip-config.h" #define NM_VARIANT_ATTRIBUTE_SPEC_DEFINE(_name, _type, ...) \ - (&((const NMVariantAttributeSpec){.name = _name, .type = _type, __VA_ARGS__})) + (&((const NMVariantAttributeSpec) {.name = _name, .type = _type, __VA_ARGS__})) gboolean _nm_utils_string_slist_validate(GSList *list, const char **valid_values); diff --git a/src/libnm-core-impl/nm-utils.c b/src/libnm-core-impl/nm-utils.c index fea13a95..6528b5fb 100644 --- a/src/libnm-core-impl/nm-utils.c +++ b/src/libnm-core-impl/nm-utils.c @@ -305,14 +305,14 @@ nm_sock_addr_endpoint_get_fixed_sockaddr(NMSockAddrEndpoint *self, gpointer sock good: switch (addr_family) { case AF_INET: - *((struct sockaddr_in *) sockaddr) = (struct sockaddr_in){ + *((struct sockaddr_in *) sockaddr) = (struct sockaddr_in) { .sin_family = AF_INET, .sin_addr = addrbin.addr4_struct, .sin_port = htons(self->port), }; return TRUE; case AF_INET6: - *((struct sockaddr_in6 *) sockaddr) = (struct sockaddr_in6){ + *((struct sockaddr_in6 *) sockaddr) = (struct sockaddr_in6) { .sin6_family = AF_INET6, .sin6_addr = addrbin.addr6, .sin6_port = htons(self->port), @@ -1309,11 +1309,11 @@ nm_utils_dns_to_variant(int addr_family, const char *const *dns, gssize len) /* We can only represent the IP address on the legacy property "ipv[46].dns". * Expose what we can. */ - if (!nm_utils_dnsname_parse(addr_family, dns[i], NULL, &ip, NULL)) + if (!nm_dns_uri_parse_plain(addr_family, dns[i], NULL, &ip)) continue; if (IS_IPv4) - g_variant_builder_add(&builder, "u", ip); + g_variant_builder_add(&builder, "u", ip.addr4); else g_variant_builder_add(&builder, "@ay", nm_g_variant_new_ay_in6addr(&ip.addr6)); } @@ -2358,7 +2358,7 @@ _nm_utils_ip_addresses_from_variant(GVariant *value, int family, bool strict, GE g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("IP address requires fields \"dest\" and \"prefix\" (idx=%u)"), + _("IP address requires fields \"address\" and \"prefix\" (idx=%u)"), i); return NULL; } @@ -2719,9 +2719,9 @@ typedef struct { } NMQdiscAttributeSpec; static const NMQdiscAttributeSpec *const tc_qdisc_attribute_spec[] = { - &(const NMQdiscAttributeSpec){"fq_codel", tc_qdisc_fq_codel_spec}, - &(const NMQdiscAttributeSpec){"sfq", tc_qdisc_sfq_spec}, - &(const NMQdiscAttributeSpec){"tbf", tc_qdisc_tbf_spec}, + &(const NMQdiscAttributeSpec) {"fq_codel", tc_qdisc_fq_codel_spec}, + &(const NMQdiscAttributeSpec) {"sfq", tc_qdisc_sfq_spec}, + &(const NMQdiscAttributeSpec) {"tbf", tc_qdisc_tbf_spec}, NULL, }; diff --git a/src/libnm-core-impl/nm-vpn-editor-plugin.c b/src/libnm-core-impl/nm-vpn-editor-plugin.c index 6181368a..fc998b57 100644 --- a/src/libnm-core-impl/nm-vpn-editor-plugin.c +++ b/src/libnm-core-impl/nm-vpn-editor-plugin.c @@ -299,6 +299,9 @@ _nm_vpn_editor_plugin_load(const char *plugin_name, return NULL; } + /* Note that factory() shouldn't be returning errors or failing. + * We can't change its prototype as it would consistute an ABI break, + * however it returning a failure would indicate a bug in the plugin. */ editor_plugin = factory(&factory_error); if (loaded_before) { diff --git a/src/libnm-core-impl/tests/test-general.c b/src/libnm-core-impl/tests/test-general.c index 8d4ea069..d581fc79 100644 --- a/src/libnm-core-impl/tests/test-general.c +++ b/src/libnm-core-impl/tests/test-general.c @@ -560,13 +560,13 @@ test_nm_hash(void) g_assert_cmpmem(NM_HASH_SEED_16(55, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), 16, - ((guint8[16]){55, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}), + ((guint8[16]) {55, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}), 16); - g_assert_cmpmem(NM_HASH_SEED_16_U64(1), 16, ((guint8[16]){0, 0, 0, 0, 0, 0, 0, 1, 0}), 16); + g_assert_cmpmem(NM_HASH_SEED_16_U64(1), 16, ((guint8[16]) {0, 0, 0, 0, 0, 0, 0, 1, 0}), 16); g_assert_cmpmem(NM_HASH_SEED_16_U64(0x1234567890ABCDEFu), 16, - ((guint8[16]){0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0}), + ((guint8[16]) {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0}), 16); g_assert_cmpint(c_siphash_hash(NM_HASH_SEED_16_U64(0x780E21E45489CC6Fu), (guint8 *) "foo", 3), @@ -1702,7 +1702,7 @@ static const NMDedupMultiObjClass dedup_obj_class = { }; #define DEDUP_OBJ_INIT(val_val, other_other) \ - (&((DedupObj){ \ + (&((DedupObj) { \ .parent = \ { \ .klass = &dedup_obj_class, \ @@ -1904,7 +1904,7 @@ _dedup_entry_assert_all(const NMDedupMultiEntry *entry, } } #define _dedup_entry_assert_all(entry, expected_idx, ...) \ - _dedup_entry_assert_all(entry, expected_idx, (const DedupObj *const[]){__VA_ARGS__, NULL}) + _dedup_entry_assert_all(entry, expected_idx, (const DedupObj *const[]) {__VA_ARGS__, NULL}) static void test_dedup_multi(void) @@ -3962,7 +3962,7 @@ typedef struct { typedef struct { const char *name; - DiffKey keys[33]; + DiffKey keys[41]; } DiffSetting; #define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0])) @@ -4037,6 +4037,9 @@ test_connection_diff_a_only(void) {NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_CONNECTION_WAIT_ACTIVATION_DELAY, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_CONNECTION_DOWN_ON_POWEROFF, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_IP_PING_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_IP_PING_ADDRESSES, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_CONNECTION_IP_PING_ADDRESSES_REQUIRE_ALL, NM_SETTING_DIFF_RESULT_IN_A}, {NULL, NM_SETTING_DIFF_RESULT_UNKNOWN}}}, {NM_SETTING_WIRED_SETTING_NAME, { @@ -4075,6 +4078,7 @@ test_connection_diff_a_only(void) {NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME_V2, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_IP4_CONFIG_DHCP_FQDN, NM_SETTING_DIFF_RESULT_IN_A}, @@ -4088,9 +4092,13 @@ test_connection_diff_a_only(void) {NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_IP_CONFIG_DHCP_REJECT_SERVERS, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_IP4_CONFIG_LINK_LOCAL, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP4_CONFIG_DHCP_IPV6_ONLY_PREFERRED, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_IP_CONFIG_AUTO_ROUTE_EXT_GW, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_IP_CONFIG_REPLACE_LOCAL_RULE, NM_SETTING_DIFF_RESULT_IN_A}, {NM_SETTING_IP_CONFIG_DHCP_SEND_RELEASE, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_ROUTED_DNS, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_SHARED_DHCP_RANGE, NM_SETTING_DIFF_RESULT_IN_A}, + {NM_SETTING_IP_CONFIG_SHARED_DHCP_LEASE_TIME, NM_SETTING_DIFF_RESULT_IN_A}, {NULL, NM_SETTING_DIFF_RESULT_UNKNOWN}, }}, }; @@ -8671,9 +8679,11 @@ test_nm_utils_ascii_str_to_int64(void) static void test_nm_utils_strstrdictkey(void) { -#define _VALUES_STATIC(_v1, _v2) \ - { \ - .v1 = _v1, .v2 = _v2, .v_static = _nm_utils_strstrdictkey_static(_v1, _v2), \ +#define _VALUES_STATIC(_v1, _v2) \ + { \ + .v1 = _v1, \ + .v2 = _v2, \ + .v_static = _nm_utils_strstrdictkey_static(_v1, _v2), \ } const struct { const char *v1; @@ -10613,7 +10623,7 @@ test_integrate_maincontext(gconstpointer test_data) loop1 = g_main_loop_new(c1, FALSE); - d = (IntegData){ + d = (IntegData) { .loop1 = loop1, .c2 = c2, }; @@ -11389,176 +11399,179 @@ test_connection_path(void) /*****************************************************************************/ static void -_t_dnsname_1(const char *str, const char *exp_addr, const char *exp_server_name) -{ - int addr_family; - NMIPAddr exp_addr_bin; - gboolean addr_family_request; - gboolean r; - int detect_addr_family; - NMIPAddr detect_addr; - const char *detect_server_name; - int *p_detect_addr_family = &detect_addr_family; - NMIPAddr *p_detect_addr = &detect_addr; - const char **p_detect_server_name = &detect_server_name; - char str_construct_buf[100]; - char str_construct_buf2[100]; - const char *str_construct; - const char *str_construct2; - gsize l; - const char *str_normalized; - gs_free char *str_normalized_alloc = NULL; +t_dns_0(const char *str) +{ + NMDnsServer server = {}; + gboolean ret; - g_assert(str); - g_assert(exp_addr); + ret = nm_dns_uri_parse(AF_UNSPEC, str, &server); - r = nm_inet_parse_bin(AF_UNSPEC, exp_addr, &addr_family, &exp_addr_bin); - g_assert(r); - g_assert(NM_IN_SET(addr_family, AF_INET, AF_INET6)); + g_assert(!ret); +} - addr_family_request = nmtst_get_rand_bool(); - if (nmtst_get_rand_bool()) - p_detect_addr = NULL; - if ((addr_family_request || !p_detect_addr) && nmtst_get_rand_bool()) - p_detect_addr_family = NULL; - if (nmtst_get_rand_bool()) - p_detect_server_name = NULL; - - r = nm_utils_dnsname_parse(addr_family_request ? addr_family : AF_UNSPEC, - str, - p_detect_addr_family, - p_detect_addr, - p_detect_server_name); - g_assert(r); - - if (p_detect_addr_family) - g_assert_cmpint(addr_family, ==, detect_addr_family); - if (p_detect_addr) - g_assert_cmpstr(nmtst_inet_to_string(addr_family, &detect_addr), ==, exp_addr); - if (p_detect_server_name) - g_assert_cmpstr(detect_server_name, ==, exp_server_name); - - r = nm_utils_dnsname_parse(addr_family == AF_INET ? AF_INET6 : AF_INET, - str, - p_detect_addr_family, - p_detect_addr, - p_detect_server_name); - g_assert(!r); - - /* Construct the expected value. */ - str_construct = nm_utils_dnsname_construct(addr_family, - &exp_addr_bin, - exp_server_name, - str_construct_buf, - sizeof(str_construct_buf)); - g_assert(str_construct); - g_assert(str_construct == str_construct_buf); - g_assert(strlen(str_construct) < sizeof(str_construct_buf)); - - /* Check that a too short buffer causes truncation. */ - l = nmtst_get_rand_uint32() % (strlen(str_construct) + 10); - str_construct2 = nm_utils_dnsname_construct(addr_family, - &exp_addr_bin, - exp_server_name, - str_construct_buf2, - l); - if (str_construct2) { - g_assert(str_construct2 == str_construct_buf2); - g_assert_cmpstr(str_construct2, ==, str_construct); - g_assert(l > strlen(str_construct)); - } else - g_assert(l <= strlen(str_construct)); +static void +dns_uri_parse_ok(const char *str, + int addr_family, + NMDnsUriScheme scheme, + const char *addr, + int port, + const char *sname, + const char *ifname) +{ + NMDnsServer dns = {}; + char addrstr[NM_INET_ADDRSTRLEN]; + gboolean ret; - if (!nm_streq(str_construct, str)) { - _t_dnsname_1(str_construct, exp_addr, exp_server_name); - } + for (int i = 0; i < 2; i++) { + gboolean af_unspec = i; - str_normalized = nm_utils_dnsname_normalize(nmtst_get_rand_bool() ? addr_family : AF_UNSPEC, - str, - &str_normalized_alloc); - g_assert(str_normalized); - if (str_normalized_alloc) { - g_assert(str_normalized == str_normalized_alloc); - g_assert_cmpstr(str_normalized, !=, str); - } else { - g_assert(str == str_normalized); + ret = nm_dns_uri_parse(af_unspec ? AF_UNSPEC : addr_family, str, &dns); + g_assert(ret); + + g_assert_cmpint(addr_family, ==, dns.addr_family); + g_assert_cmpint(port, ==, dns.port); + g_assert_cmpstr(sname, ==, dns.servername); + g_assert_cmpstr(ifname ?: "", ==, dns.interface); + + nm_inet_ntop(dns.addr_family, &dns.addr, addrstr); + g_assert_cmpstr(addrstr, ==, addr); + + /* Parse with the wrong address family must fail */ + ret = nm_dns_uri_parse(addr_family == AF_INET ? AF_INET6 : AF_INET, str, &dns); + g_assert(!ret); } - g_assert_cmpstr(str_normalized, ==, str_construct); +} + +#define t_dns_1(str, af, scheme, addr, port, sname, ifname) \ + dns_uri_parse_ok((str), \ + (AF_##af), \ + (NM_DNS_URI_SCHEME_##scheme), \ + (addr), \ + (port), \ + (sname), \ + (ifname)) + +static void +test_dns_uri_parse(void) +{ + /* clang-format off */ + t_dns_1("dns+tls://8.8.8.8", INET, TLS, "8.8.8.8", -1, NULL, NULL); + t_dns_1("dns+tls://8.8.8.8", INET, TLS, "8.8.8.8", -1, NULL, NULL); + t_dns_1("dns+tls://1.2.3.4#name", INET, TLS, "1.2.3.4", -1, "name", NULL); + t_dns_1("dns+tls://1.2.3.4#a.b.c", INET, TLS, "1.2.3.4", -1, "a.b.c", NULL); + t_dns_1("dns+tls://1.2.3.4:53", INET, TLS, "1.2.3.4", 53, NULL, NULL); + t_dns_1("dns+tls://1.2.3.4:53#foobar", INET, TLS, "1.2.3.4", 53, "foobar", NULL); + t_dns_1("dns+tls://192.168.120.250:99", INET, TLS, "192.168.120.250", 99, NULL, NULL); + t_dns_1("dns+udp://8.8.8.8:65535", INET, UDP, "8.8.8.8", 65535, NULL, NULL); + + t_dns_1("dns+udp://[fd01::1]", INET6, UDP, "fd01::1", -1, NULL, NULL); + t_dns_1("dns+tls://[fd01::2]:5353", INET6, UDP, "fd01::2", 5353, NULL, NULL); + t_dns_1("dns+tls://[::1]#name", INET6, UDP, "::1", -1, "name", NULL); + t_dns_1("dns+tls://[::2]:65535#name", INET6, UDP, "::2", 65535, "name", NULL); + t_dns_1("dns+udp://[::ffff:1.2.3.4]", INET6, UDP, "::ffff:1.2.3.4", -1, NULL, NULL); + t_dns_1("dns+tls://[fe80::1%eth0]", INET6, UDP, "fe80::1", -1, NULL, "eth0"); + t_dns_1("dns+tls://[fe80::2%en1]:53#a", INET6, UDP, "fe80::2", 53, "a", "en1"); + t_dns_1("dns+tls://[fe80::1%en3456789012345]", INET6, UDP, "fe80::1", -1, NULL, "en3456789012345"); + + t_dns_1("1.2.3.4", INET, NONE, "1.2.3.4", -1, NULL, NULL); + t_dns_1("1.2.3.4#foo", INET, NONE, "1.2.3.4", -1, "foo", NULL); + t_dns_1("1::#x", INET6, NONE, "1::", -1, "x", NULL); + t_dns_1("1::0#x", INET6, NONE, "1::", -1, "x", NULL); + t_dns_1("192.168.0.1", INET, NONE, "192.168.0.1", -1, NULL, NULL); + t_dns_1("192.168.0.1#tst.com", INET, NONE, "192.168.0.1", -1, "tst.com", NULL); + t_dns_1("fe80::18", INET6, NONE, "fe80::18", -1, NULL, NULL); + t_dns_1("fe80::18#foo.com", INET6, NONE, "fe80::18", -1, "foo.com", NULL); + /* clang-format on */ - nm_clear_g_free(&str_normalized_alloc); - str_normalized = nm_utils_dnsname_normalize(addr_family == AF_INET ? AF_INET6 : AF_INET, - str, - &str_normalized_alloc); - g_assert(!str_normalized); - g_assert(!str_normalized_alloc); + t_dns_0("http://8.8.8.8"); /* unsupported schema */ + t_dns_0("dns+udp://1.2.3.4#name"); /* servername not supported for plain UDP */ + t_dns_0("dns+tls://1.2.3"); /* invalid address */ + t_dns_0("dns+tls://fd01::1"); /* IPv6 requires brackets */ + t_dns_0("dns+tls://[fd13:a:aaaa]"); /* invalid address */ + t_dns_0("dns+tls://1.2.3.4:1:1"); /* invalid syntax */ + t_dns_0("dns+tls://1.2.3.4#name#name"); /* invalid syntax */ + t_dns_0("dns+tls://1.2.3.4%eth0"); /* interface only allowed for IPv6 */ + t_dns_0("dns+tls://[2001::1%eth0]"); /* interface only allowed for IPv6 link-local */ + t_dns_0("dns+tls://[fe80::1%en34567890123456]"); /* interface name too long */ + t_dns_0("1.2.3.4#"); + t_dns_0("1::0#"); + t_dns_0("192.168.0.1:53"); + t_dns_0("192.168.0.1:53#example.com"); + t_dns_0("fe80::18%19"); + t_dns_0("fe80::18%lo"); + t_dns_0("[fe80::18]:53"); + t_dns_0("[fe80::18]:53%19"); + t_dns_0("[fe80::18]:53%lo"); + t_dns_0("fe80::18%19#hoge.com"); + t_dns_0("[fe80::18]:53#hoge.com"); + t_dns_0("[fe80::18]:53%19"); + t_dns_0("[fe80::18]:53%19#hoge.com"); + t_dns_0("[fe80::18]:53%lo"); + t_dns_0("[fe80::18]:53%lo#hoge.com"); +} + +static void +test_dns_uri_parse_plain(void) +{ + struct { + const char *input; + int input_af; + gboolean result; + const char *addrstr; + } values[] = { + {"1.2.3.4", AF_INET, TRUE, "1.2.3.4"}, + {"1.2.3.4", AF_INET6, FALSE, NULL}, + {"1.2.3.4", AF_UNSPEC, TRUE, "1.2.3.4"}, + {"1234:5555:ffff:dddd::4321", AF_INET, FALSE, NULL}, + {"1234:5555:ffff:dddd::4321", AF_INET6, TRUE, "1234:5555:ffff:dddd::4321"}, + {"1234:5555:ffff:dddd::4321", AF_UNSPEC, TRUE, "1234:5555:ffff:dddd::4321"}, + {"192.0.2.1#example.com", AF_INET, TRUE, "192.0.2.1"}, + {"192.0.2.1#example.com", AF_UNSPEC, TRUE, "192.0.2.1"}, + {"192.0.2.1#example.com", AF_INET6, FALSE, NULL}, + {"dns+tls://1.2.3.4", AF_INET, FALSE, NULL}, + {"dns+tls://[fd01::1]", AF_INET, FALSE, NULL}, + {"dns+udp://1.2.3.4:53", AF_INET, TRUE, "1.2.3.4"}, + {"dns+udp://1.2.3.4:54", AF_INET, FALSE, NULL}, + {"dns+udp://[fd01::1]", AF_INET6, TRUE, "fd01::1"}, + {"dns+udp://[fd01::1]:53", AF_INET6, TRUE, "fd01::1"}, + {"dns+udp://[fd01::1]:60000", AF_INET, FALSE, NULL}, + }; + guint i; + + for (i = 0; i < G_N_ELEMENTS(values); i++) { + char addrstr[NM_INET_ADDRSTRLEN]; + gboolean result; + NMIPAddr addr; + + result = nm_dns_uri_parse_plain(values[i].input_af, values[i].input, addrstr, &addr); + g_assert_cmpint(result, ==, values[i].result); + if (result) { + char buf[NM_INET_ADDRSTRLEN]; + + nm_inet_ntop(strchr(addrstr, ':') ? AF_INET6 : AF_INET, addr.addr_ptr, buf); + g_assert_cmpstr(buf, ==, addrstr); + g_assert_cmpstr(addrstr, ==, values[i].addrstr); + } + } } static void -_t_dnsname_0(const char *str) +t_dns_uri_normalize(const char *input, const char *expected) { - gboolean addr_family_request; - int detect_addr_family; - NMIPAddr detect_addr; - const char *detect_server_name; - int *p_detect_addr_family = &detect_addr_family; - NMIPAddr *p_detect_addr = &detect_addr; - const char **p_detect_server_name = &detect_server_name; - const char *str_normalized; - gs_free char *str_normalized_alloc = NULL; - gboolean r; + const char *str; + gs_free char *str_free = NULL; - g_assert(str); + str = nm_dns_uri_normalize(AF_UNSPEC, input, &str_free); + g_assert_cmpstr(str, ==, expected); +} - addr_family_request = nmtst_get_rand_bool(); - if (nmtst_get_rand_bool()) - p_detect_addr = NULL; - if ((addr_family_request || !p_detect_addr) && nmtst_get_rand_bool()) - p_detect_addr_family = NULL; - if (nmtst_get_rand_bool()) - p_detect_server_name = NULL; - - r = nm_utils_dnsname_parse(addr_family_request ? nmtst_rand_select(AF_INET, AF_INET6) - : AF_UNSPEC, - str, - p_detect_addr_family, - p_detect_addr, - p_detect_server_name); - g_assert(!r); - - str_normalized = nm_utils_dnsname_normalize(nmtst_rand_select(AF_UNSPEC, AF_INET, AF_INET6), - str, - &str_normalized_alloc); - g_assert(!str_normalized); - g_assert(!str_normalized_alloc); -} - -static void -test_dnsname(void) -{ - _t_dnsname_1("1.2.3.4", "1.2.3.4", NULL); - _t_dnsname_1("1.2.3.4#foo", "1.2.3.4", "foo"); - _t_dnsname_1("1::#x", "1::", "x"); - _t_dnsname_1("1::0#x", "1::", "x"); - _t_dnsname_1("192.168.0.1", "192.168.0.1", NULL); - _t_dnsname_1("192.168.0.1#test.com", "192.168.0.1", "test.com"); - _t_dnsname_1("fe80::18", "fe80::18", NULL); - _t_dnsname_1("fe80::18#hoge.com", "fe80::18", "hoge.com"); - - _t_dnsname_0("1.2.3.4#"); - _t_dnsname_0("1::0#"); - _t_dnsname_0("192.168.0.1:53"); - _t_dnsname_0("192.168.0.1:53#example.com"); - _t_dnsname_0("fe80::18%19"); - _t_dnsname_0("fe80::18%lo"); - _t_dnsname_0("[fe80::18]:53"); - _t_dnsname_0("[fe80::18]:53%19"); - _t_dnsname_0("[fe80::18]:53%lo"); - _t_dnsname_0("fe80::18%19#hoge.com"); - _t_dnsname_0("[fe80::18]:53#hoge.com"); - _t_dnsname_0("[fe80::18]:53%19"); - _t_dnsname_0("[fe80::18]:53%19#hoge.com"); - _t_dnsname_0("[fe80::18]:53%lo"); - _t_dnsname_0("[fe80::18]:53%lo#hoge.com"); +static void +test_dns_uri_normalize(void) +{ + t_dns_uri_normalize("8.8.8.8", "8.8.8.8"); + t_dns_uri_normalize("dns+tls://[2001:0:0::1234]:999#name", "dns+tls://[2001::1234]:999#name"); + t_dns_uri_normalize("dns+udp://[0::1]:0123", "dns+udp://[::1]:123"); + t_dns_uri_normalize("8.8.8.888", NULL); } /*****************************************************************************/ @@ -11937,7 +11950,9 @@ main(int argc, char **argv) g_test_add_func("/core/general/test_system_encodings", test_system_encodings); g_test_add_func("/core/general/test_direct_string_is_refstr", test_direct_string_is_refstr); g_test_add_func("/core/general/test_connection_path", test_connection_path); - g_test_add_func("/core/general/test_dnsname", test_dnsname); + g_test_add_func("/core/general/test_dns_uri_parse", test_dns_uri_parse); + g_test_add_func("/core/general/test_dns_uri_get_legacy", test_dns_uri_parse_plain); + g_test_add_func("/core/general/test_dns_uri_normalize", test_dns_uri_normalize); g_test_add_func("/core/general/test_dhcp_iaid_hexstr", test_dhcp_iaid_hexstr); return g_test_run(); diff --git a/src/libnm-core-impl/tests/test-keyfile.c b/src/libnm-core-impl/tests/test-keyfile.c index 1912782e..5c66196c 100644 --- a/src/libnm-core-impl/tests/test-keyfile.c +++ b/src/libnm-core-impl/tests/test-keyfile.c @@ -943,7 +943,7 @@ test_invalid_option(void) nm_setting_option_set_boolean(s_ethtool, NM_ETHTOOL_OPTNAME_PAUSE_RX, TRUE); - data = (InvalidOptionWriteData){}; + data = (InvalidOptionWriteData) {}; kf = nm_keyfile_write(con, NM_KEYFILE_HANDLER_FLAGS_NONE, _invalid_option_write_handler, @@ -956,7 +956,7 @@ test_invalid_option(void) nmtst_assert_connection_verifies_without_normalization(con); - data = (InvalidOptionWriteData){}; + data = (InvalidOptionWriteData) {}; kf = nm_keyfile_write(con, NM_KEYFILE_HANDLER_FLAGS_NONE, _invalid_option_write_handler, @@ -967,7 +967,7 @@ test_invalid_option(void) nm_setting_option_set(s_ethtool, "bogus", g_variant_new_int64(0)); - data = (InvalidOptionWriteData){ + data = (InvalidOptionWriteData) { .expect = TRUE, }; kf = nm_keyfile_write(con, diff --git a/src/libnm-core-impl/tests/test-setting.c b/src/libnm-core-impl/tests/test-setting.c index f3309166..2064162a 100644 --- a/src/libnm-core-impl/tests/test-setting.c +++ b/src/libnm-core-impl/tests/test-setting.c @@ -799,29 +799,29 @@ static void test_bond_compare(void) { test_bond_compare_options(TRUE, - ((const char *[]){"mode", "balance-rr", "miimon", "1", NULL}), - ((const char *[]){"mode", "balance-rr", "miimon", "1", NULL})); + ((const char *[]) {"mode", "balance-rr", "miimon", "1", NULL}), + ((const char *[]) {"mode", "balance-rr", "miimon", "1", NULL})); test_bond_compare_options(FALSE, - ((const char *[]){"mode", "balance-rr", "miimon", "1", NULL}), - ((const char *[]){"mode", "balance-rr", "miimon", "2", NULL})); + ((const char *[]) {"mode", "balance-rr", "miimon", "1", NULL}), + ((const char *[]) {"mode", "balance-rr", "miimon", "2", NULL})); test_bond_compare_options(FALSE, - ((const char *[]){"miimon", "1", NULL}), - ((const char *[]){"miimon", "1", "updelay", "0", NULL})); + ((const char *[]) {"miimon", "1", NULL}), + ((const char *[]) {"miimon", "1", "updelay", "0", NULL})); test_bond_compare_options(FALSE, - ((const char *[]){"num_grat_arp", "2", NULL}), - ((const char *[]){"num_grat_arp", "1", NULL})); + ((const char *[]) {"num_grat_arp", "2", NULL}), + ((const char *[]) {"num_grat_arp", "1", NULL})); test_bond_compare_options(FALSE, - ((const char *[]){"num_grat_arp", "3", NULL}), - ((const char *[]){"num_unsol_na", "3", NULL})); + ((const char *[]) {"num_grat_arp", "3", NULL}), + ((const char *[]) {"num_unsol_na", "3", NULL})); test_bond_compare_options(FALSE, - ((const char *[]){"num_grat_arp", "4", NULL}), - ((const char *[]){"num_unsol_na", "4", "num_grat_arp", "4", NULL})); + ((const char *[]) {"num_grat_arp", "4", NULL}), + ((const char *[]) {"num_unsol_na", "4", "num_grat_arp", "4", NULL})); test_bond_compare_options(FALSE, - ((const char *[]){"mode", "balance-rr", "miimon", "100", NULL}), - ((const char *[]){"mode", "balance-rr", NULL})); + ((const char *[]) {"mode", "balance-rr", "miimon", "100", NULL}), + ((const char *[]) {"mode", "balance-rr", NULL})); } static void @@ -856,20 +856,25 @@ static void test_bond_normalize(void) { test_bond_normalize_options( - ((const char *[]){"mode", "802.3ad", "ad_actor_system", "00:02:03:04:05:06", NULL}), - ((const char *[]){"mode", "802.3ad", "ad_actor_system", "00:02:03:04:05:06", NULL})); - test_bond_normalize_options(((const char *[]){"mode", "1", "miimon", "1", NULL}), - ((const char *[]){"mode", "active-backup", "miimon", "1", NULL})); + ((const char *[]) {"mode", "802.3ad", "ad_actor_system", "00:02:03:04:05:06", NULL}), + ((const char *[]) {"mode", "802.3ad", "ad_actor_system", "00:02:03:04:05:06", NULL})); + test_bond_normalize_options(((const char *[]) {"mode", "1", "miimon", "1", NULL}), + ((const char *[]) {"mode", "active-backup", "miimon", "1", NULL})); test_bond_normalize_options( - ((const char *[]){"mode", "balance-alb", "tlb_dynamic_lb", "1", NULL}), - ((const char *[]){"mode", "balance-alb", "tlb_dynamic_lb", "1", NULL})); + ((const char *[]) {"mode", "balance-alb", "tlb_dynamic_lb", "1", NULL}), + ((const char *[]) {"mode", "balance-alb", "tlb_dynamic_lb", "1", NULL})); test_bond_normalize_options( - ((const char *[]){"mode", "balance-tlb", "tlb_dynamic_lb", "1", NULL}), - ((const char *[]){"mode", "balance-tlb", "tlb_dynamic_lb", "1", NULL})); + ((const char *[]) {"mode", "balance-tlb", "tlb_dynamic_lb", "1", NULL}), + ((const char *[]) {"mode", "balance-tlb", "tlb_dynamic_lb", "1", NULL})); test_bond_normalize_options( - ((const char - *[]){"mode", "balance-rr", "ad_actor_sys_prio", "4", "packets_per_slave", "3", NULL}), - ((const char *[]){"mode", "balance-rr", "packets_per_slave", "3", NULL})); + ((const char *[]) {"mode", + "balance-rr", + "ad_actor_sys_prio", + "4", + "packets_per_slave", + "3", + NULL}), + ((const char *[]) {"mode", "balance-rr", "packets_per_slave", "3", NULL})); } /*****************************************************************************/ @@ -2379,6 +2384,85 @@ test_ethtool_eee(void) /*****************************************************************************/ static void +test_ethtool_fec(void) +{ + gs_unref_object NMConnection *con = NULL; + gs_unref_object NMConnection *con2 = NULL; + gs_unref_object NMConnection *con3 = NULL; + gs_unref_variant GVariant *variant = NULL; + gs_free_error GError *error = NULL; + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + NMSettingConnection *s_con; + NMSettingEthtool *s_ethtool; + NMSettingEthtool *s_ethtool2; + NMSettingEthtool *s_ethtool3; + guint32 out_value; + guint32 expected_fec_mode = + NM_SETTING_ETHTOOL_FEC_MODE_AUTO | NM_SETTING_ETHTOOL_FEC_MODE_BASER; + + con = + nmtst_create_minimal_connection("ethtool-fec", NULL, NM_SETTING_WIRED_SETTING_NAME, &s_con); + s_ethtool = NM_SETTING_ETHTOOL(nm_setting_ethtool_new()); + nm_connection_add_setting(con, NM_SETTING(s_ethtool)); + + nm_setting_option_set_uint32(NM_SETTING(s_ethtool), + NM_ETHTOOL_OPTNAME_FEC_MODE, + expected_fec_mode); + + g_assert_true(nm_setting_option_get_uint32(NM_SETTING(s_ethtool), + NM_ETHTOOL_OPTNAME_FEC_MODE, + &out_value)); + g_assert_true(out_value == expected_fec_mode); + + nmtst_connection_normalize(con); + + variant = nm_connection_to_dbus(con, NM_CONNECTION_SERIALIZE_ALL); + + con2 = nm_simple_connection_new_from_dbus(variant, &error); + nmtst_assert_success(con2, error); + + s_ethtool2 = NM_SETTING_ETHTOOL(nm_connection_get_setting(con2, NM_TYPE_SETTING_ETHTOOL)); + + g_assert_true(nm_setting_option_get_uint32(NM_SETTING(s_ethtool2), + NM_ETHTOOL_OPTNAME_FEC_MODE, + &out_value)); + g_assert_true(out_value == expected_fec_mode); + + nmtst_assert_connection_verifies_without_normalization(con2); + + nmtst_assert_connection_equals(con, FALSE, con2, FALSE); + + con2 = nm_simple_connection_new_from_dbus(variant, &error); + nmtst_assert_success(con2, error); + + keyfile = nm_keyfile_write(con, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error); + nmtst_assert_success(keyfile, error); + + con3 = nm_keyfile_read(keyfile, + "/ignored/current/working/directory/for/loading/relative/paths", + NM_KEYFILE_HANDLER_FLAGS_NONE, + NULL, + NULL, + &error); + nmtst_assert_success(con3, error); + + nm_keyfile_read_ensure_id(con3, "unused-because-already-has-id"); + nm_keyfile_read_ensure_uuid(con3, "unused-because-already-has-uuid"); + + nmtst_connection_normalize(con3); + + nmtst_assert_connection_equals(con, FALSE, con3, FALSE); + + s_ethtool3 = NM_SETTING_ETHTOOL(nm_connection_get_setting(con3, NM_TYPE_SETTING_ETHTOOL)); + + g_assert_true(nm_setting_option_get_uint32(NM_SETTING(s_ethtool3), + NM_ETHTOOL_OPTNAME_FEC_MODE, + &out_value)); + g_assert_true(out_value == expected_fec_mode); +} +/*****************************************************************************/ + +static void test_sriov_vf(void) { NMSriovVF *vf1, *vf2; @@ -5481,6 +5565,7 @@ main(int argc, char **argv) g_test_add_func("/libnm/settings/ethtool/ring", test_ethtool_ring); g_test_add_func("/libnm/settings/ethtool/pause", test_ethtool_pause); g_test_add_func("/libnm/settings/ethtool/eee", test_ethtool_eee); + g_test_add_func("/libnm/settings/ethtool/fec", test_ethtool_fec); g_test_add_func("/libnm/settings/6lowpan/1", test_6lowpan_1); diff --git a/src/libnm-core-intern/nm-core-internal.h b/src/libnm-core-intern/nm-core-internal.h index 4677fb16..aa96c526 100644 --- a/src/libnm-core-intern/nm-core-internal.h +++ b/src/libnm-core-intern/nm-core-internal.h @@ -44,6 +44,7 @@ #include "nm-setting-ip-tunnel.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" +#include "nm-setting-ipvlan.h" #include "nm-setting-link.h" #include "nm-setting-loopback.h" #include "nm-setting-macsec.h" @@ -547,6 +548,8 @@ GPtrArray *_nm_setting_bridge_port_get_vlans(NMSettingBridgePort *setting); GArray *_nm_setting_connection_get_secondaries(NMSettingConnection *setting); +GArray *_nm_setting_connection_get_ip_ping_addresses(NMSettingConnection *setting); + gboolean nm_setting_connection_permissions_user_allowed_by_uid(NMSettingConnection *setting, gulong uid); diff --git a/src/libnm-core-intern/nm-keyfile-utils.h b/src/libnm-core-intern/nm-keyfile-utils.h index b7758c05..604daf51 100644 --- a/src/libnm-core-intern/nm-keyfile-utils.h +++ b/src/libnm-core-intern/nm-keyfile-utils.h @@ -88,6 +88,4 @@ const char *nm_keyfile_key_encode(const char *name, char **out_to_free); const char *nm_keyfile_key_decode(const char *key, char **out_to_free); -void nm_keyfile_add_group(GKeyFile *keyfile, const char *group); - #endif /* __NM_KEYFILE_UTILS_H__ */ diff --git a/src/libnm-core-intern/nm-meta-setting-base-impl.h b/src/libnm-core-intern/nm-meta-setting-base-impl.h index 9226183f..c03285eb 100644 --- a/src/libnm-core-intern/nm-meta-setting-base-impl.h +++ b/src/libnm-core-intern/nm-meta-setting-base-impl.h @@ -128,6 +128,7 @@ typedef enum _nm_packed { NM_META_SETTING_TYPE_IP_TUNNEL, NM_META_SETTING_TYPE_IP4_CONFIG, NM_META_SETTING_TYPE_IP6_CONFIG, + NM_META_SETTING_TYPE_IPVLAN, NM_META_SETTING_TYPE_LINK, NM_META_SETTING_TYPE_LOOPBACK, NM_META_SETTING_TYPE_MACSEC, diff --git a/src/libnm-core-public/meson.build b/src/libnm-core-public/meson.build index b5ed71e8..97888467 100644 --- a/src/libnm-core-public/meson.build +++ b/src/libnm-core-public/meson.build @@ -30,6 +30,7 @@ libnm_core_headers = files( 'nm-setting-ip-tunnel.h', 'nm-setting-ip4-config.h', 'nm-setting-ip6-config.h', + 'nm-setting-ipvlan.h', 'nm-setting-link.h', 'nm-setting-loopback.h', 'nm-setting-macsec.h', diff --git a/src/libnm-core-public/nm-core-types.h b/src/libnm-core-public/nm-core-types.h index d9a8225e..a0d6bc82 100644 --- a/src/libnm-core-public/nm-core-types.h +++ b/src/libnm-core-public/nm-core-types.h @@ -35,6 +35,7 @@ typedef struct _NMSettingIP4Config NMSettingIP4Config; typedef struct _NMSettingIP6Config NMSettingIP6Config; typedef struct _NMSettingIPConfig NMSettingIPConfig; typedef struct _NMSettingIPTunnel NMSettingIPTunnel; +typedef struct _NMSettingIpvlan NMSettingIpvlan; typedef struct _NMSettingInfiniband NMSettingInfiniband; typedef struct _NMSettingLink NMSettingLink; typedef struct _NMSettingLoopback NMSettingLoopback; diff --git a/src/libnm-core-public/nm-dbus-interface.h b/src/libnm-core-public/nm-dbus-interface.h index 9c737dbe..d6267610 100644 --- a/src/libnm-core-public/nm-dbus-interface.h +++ b/src/libnm-core-public/nm-dbus-interface.h @@ -40,6 +40,7 @@ #define NM_DBUS_INTERFACE_DEVICE_HSR NM_DBUS_INTERFACE_DEVICE ".Hsr" #define NM_DBUS_INTERFACE_DEVICE_INFINIBAND NM_DBUS_INTERFACE_DEVICE ".Infiniband" #define NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL NM_DBUS_INTERFACE_DEVICE ".IPTunnel" +#define NM_DBUS_INTERFACE_DEVICE_IPVLAN NM_DBUS_INTERFACE_DEVICE ".Ipvlan" #define NM_DBUS_INTERFACE_DEVICE_LOOPBACK NM_DBUS_INTERFACE_DEVICE ".Loopback" #define NM_DBUS_INTERFACE_DEVICE_MACSEC NM_DBUS_INTERFACE_DEVICE ".Macsec" #define NM_DBUS_INTERFACE_DEVICE_MACVLAN NM_DBUS_INTERFACE_DEVICE ".Macvlan" @@ -239,6 +240,7 @@ typedef enum { * @NM_DEVICE_TYPE_VRF: A VRF (Virtual Routing and Forwarding) interface. Since: 1.24. * @NM_DEVICE_TYPE_LOOPBACK: a loopback interface. Since: 1.42. * @NM_DEVICE_TYPE_HSR: A HSR/PRP device. Since: 1.46. + * @NM_DEVICE_TYPE_IPVLAN: A IPVLAN device. Since: 1.52. * * #NMDeviceType values indicate the type of hardware represented by a * device object. @@ -278,6 +280,7 @@ typedef enum { NM_DEVICE_TYPE_VRF = 31, NM_DEVICE_TYPE_LOOPBACK = 32, NM_DEVICE_TYPE_HSR = 33, + NM_DEVICE_TYPE_IPVLAN = 34, } NMDeviceType; /** diff --git a/src/libnm-core-public/nm-setting-connection.h b/src/libnm-core-public/nm-setting-connection.h index 4cf67346..6547c5be 100644 --- a/src/libnm-core-public/nm-setting-connection.h +++ b/src/libnm-core-public/nm-setting-connection.h @@ -33,38 +33,41 @@ G_BEGIN_DECLS #define NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MAX 999 #define NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT 0 -#define NM_SETTING_CONNECTION_ID "id" -#define NM_SETTING_CONNECTION_UUID "uuid" -#define NM_SETTING_CONNECTION_STABLE_ID "stable-id" -#define NM_SETTING_CONNECTION_INTERFACE_NAME "interface-name" -#define NM_SETTING_CONNECTION_TYPE "type" -#define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect" -#define NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY "autoconnect-priority" -#define NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES "autoconnect-retries" -#define NM_SETTING_CONNECTION_MULTI_CONNECT "multi-connect" -#define NM_SETTING_CONNECTION_TIMESTAMP "timestamp" -#define NM_SETTING_CONNECTION_READ_ONLY "read-only" -#define NM_SETTING_CONNECTION_PERMISSIONS "permissions" -#define NM_SETTING_CONNECTION_ZONE "zone" -#define NM_SETTING_CONNECTION_MASTER "master" -#define NM_SETTING_CONNECTION_CONTROLLER "controller" -#define NM_SETTING_CONNECTION_SLAVE_TYPE "slave-type" -#define NM_SETTING_CONNECTION_PORT_TYPE "port-type" -#define NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES "autoconnect-slaves" -#define NM_SETTING_CONNECTION_AUTOCONNECT_PORTS "autoconnect-ports" -#define NM_SETTING_CONNECTION_SECONDARIES "secondaries" -#define NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT "gateway-ping-timeout" -#define NM_SETTING_CONNECTION_METERED "metered" -#define NM_SETTING_CONNECTION_LLDP "lldp" -#define NM_SETTING_CONNECTION_AUTH_RETRIES "auth-retries" -#define NM_SETTING_CONNECTION_MDNS "mdns" -#define NM_SETTING_CONNECTION_LLMNR "llmnr" -#define NM_SETTING_CONNECTION_DNS_OVER_TLS "dns-over-tls" -#define NM_SETTING_CONNECTION_MPTCP_FLAGS "mptcp-flags" -#define NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT "wait-device-timeout" -#define NM_SETTING_CONNECTION_MUD_URL "mud-url" -#define NM_SETTING_CONNECTION_WAIT_ACTIVATION_DELAY "wait-activation-delay" -#define NM_SETTING_CONNECTION_DOWN_ON_POWEROFF "down-on-poweroff" +#define NM_SETTING_CONNECTION_ID "id" +#define NM_SETTING_CONNECTION_UUID "uuid" +#define NM_SETTING_CONNECTION_STABLE_ID "stable-id" +#define NM_SETTING_CONNECTION_INTERFACE_NAME "interface-name" +#define NM_SETTING_CONNECTION_TYPE "type" +#define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect" +#define NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY "autoconnect-priority" +#define NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES "autoconnect-retries" +#define NM_SETTING_CONNECTION_MULTI_CONNECT "multi-connect" +#define NM_SETTING_CONNECTION_TIMESTAMP "timestamp" +#define NM_SETTING_CONNECTION_READ_ONLY "read-only" +#define NM_SETTING_CONNECTION_PERMISSIONS "permissions" +#define NM_SETTING_CONNECTION_ZONE "zone" +#define NM_SETTING_CONNECTION_MASTER "master" +#define NM_SETTING_CONNECTION_CONTROLLER "controller" +#define NM_SETTING_CONNECTION_SLAVE_TYPE "slave-type" +#define NM_SETTING_CONNECTION_PORT_TYPE "port-type" +#define NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES "autoconnect-slaves" +#define NM_SETTING_CONNECTION_AUTOCONNECT_PORTS "autoconnect-ports" +#define NM_SETTING_CONNECTION_SECONDARIES "secondaries" +#define NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT "gateway-ping-timeout" +#define NM_SETTING_CONNECTION_METERED "metered" +#define NM_SETTING_CONNECTION_LLDP "lldp" +#define NM_SETTING_CONNECTION_AUTH_RETRIES "auth-retries" +#define NM_SETTING_CONNECTION_MDNS "mdns" +#define NM_SETTING_CONNECTION_LLMNR "llmnr" +#define NM_SETTING_CONNECTION_DNS_OVER_TLS "dns-over-tls" +#define NM_SETTING_CONNECTION_MPTCP_FLAGS "mptcp-flags" +#define NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT "wait-device-timeout" +#define NM_SETTING_CONNECTION_MUD_URL "mud-url" +#define NM_SETTING_CONNECTION_WAIT_ACTIVATION_DELAY "wait-activation-delay" +#define NM_SETTING_CONNECTION_DOWN_ON_POWEROFF "down-on-poweroff" +#define NM_SETTING_CONNECTION_IP_PING_TIMEOUT "ip-ping-timeout" +#define NM_SETTING_CONNECTION_IP_PING_ADDRESSES "ip-ping-addresses" +#define NM_SETTING_CONNECTION_IP_PING_ADDRESSES_REQUIRE_ALL "ip-ping-addresses-require-all" /* Types for property values */ /** @@ -279,6 +282,28 @@ nm_setting_connection_get_down_on_poweroff(NMSettingConnection *setting); NM_AVAILABLE_IN_1_26 const char *nm_setting_connection_get_mud_url(NMSettingConnection *setting); +NM_AVAILABLE_IN_1_52 +guint32 nm_setting_connection_get_ip_ping_timeout(NMSettingConnection *setting); + +NM_AVAILABLE_IN_1_52 +const char *nm_setting_connection_get_ip_ping_address(NMSettingConnection *setting, guint32 idx); + +NM_AVAILABLE_IN_1_52 +gboolean nm_setting_connection_add_ip_ping_address(NMSettingConnection *setting, + const char *address); +NM_AVAILABLE_IN_1_52 +void nm_setting_connection_remove_ip_ping_address(NMSettingConnection *setting, guint32 idx); + +NM_AVAILABLE_IN_1_52 +gboolean nm_setting_connection_remove_ip_ping_address_by_value(NMSettingConnection *setting, + const char *address); + +NM_AVAILABLE_IN_1_52 +void nm_setting_connection_clear_ip_ping_addresses(NMSettingConnection *setting); + +NM_AVAILABLE_IN_1_52 +NMTernary nm_setting_connection_get_ip_ping_addresses_require_all(NMSettingConnection *setting); + G_END_DECLS #endif /* __NM_SETTING_CONNECTION_H__ */ diff --git a/src/libnm-core-public/nm-setting-ethtool.h b/src/libnm-core-public/nm-setting-ethtool.h index fe1fbc0e..867bb0f2 100644 --- a/src/libnm-core-public/nm-setting-ethtool.h +++ b/src/libnm-core-public/nm-setting-ethtool.h @@ -32,6 +32,9 @@ gboolean nm_ethtool_optname_is_channels(const char *optname); NM_AVAILABLE_IN_1_46 gboolean nm_ethtool_optname_is_eee(const char *optname); +NM_AVAILABLE_IN_1_52 +gboolean nm_ethtool_optname_is_fec(const char *optname); + /*****************************************************************************/ #define NM_TYPE_SETTING_ETHTOOL (nm_setting_ethtool_get_type()) @@ -74,6 +77,30 @@ NM_AVAILABLE_IN_1_14 NM_DEPRECATED_IN_1_26 void nm_setting_ethtool_clear_features(NMSettingEthtool *setting); +/** + * NMSettingEthtoolFecMode: + * @NM_SETTING_ETHTOOL_FEC_MODE_NONE: FEC mode configuration is not supported. + * @NM_SETTING_ETHTOOL_FEC_MODE_AUTO: Select default/best FEC mode automatically. + * @NM_SETTING_ETHTOOL_FEC_MODE_OFF: No FEC mode. + * @NM_SETTING_ETHTOOL_FEC_MODE_RS: Reed-Solomon FEC Mode. + * @NM_SETTING_ETHTOOL_FEC_MODE_BASER: Base-R/Reed-Solomon FEC Mode. + * @NM_SETTING_ETHTOOL_FEC_MODE_LLRS: Low Latency Reed Solomon FEC Mode. + * + * These flags modify the ethtool FEC(Forward Error Correction) mode. + * + * Since: 1.52 + **/ +typedef enum { /*< flags >*/ + NM_SETTING_ETHTOOL_FEC_MODE_NONE = 1 << 0, /*< skip >*/ + NM_SETTING_ETHTOOL_FEC_MODE_AUTO = 1 << 1, + NM_SETTING_ETHTOOL_FEC_MODE_OFF = 1 << 2, + NM_SETTING_ETHTOOL_FEC_MODE_RS = 1 << 3, + NM_SETTING_ETHTOOL_FEC_MODE_BASER = 1 << 4, + NM_SETTING_ETHTOOL_FEC_MODE_LLRS = 1 << 5, + /* New constant should align with linux/ethtool.h ETHTOOL_FEC_XXX */ + _NM_SETTING_ETHTOOL_FEC_MODE_LAST = NM_SETTING_ETHTOOL_FEC_MODE_LLRS, /*< skip >*/ +} NMSettingEthtoolFecMode; + G_END_DECLS #endif /* __NM_SETTING_ETHTOOL_H__ */ diff --git a/src/libnm-core-public/nm-setting-gsm.h b/src/libnm-core-public/nm-setting-gsm.h index dd5b0b26..c8663502 100644 --- a/src/libnm-core-public/nm-setting-gsm.h +++ b/src/libnm-core-public/nm-setting-gsm.h @@ -26,21 +26,30 @@ G_BEGIN_DECLS #define NM_SETTING_GSM_SETTING_NAME "gsm" -#define NM_SETTING_GSM_AUTO_CONFIG "auto-config" -#define NM_SETTING_GSM_USERNAME "username" -#define NM_SETTING_GSM_PASSWORD "password" -#define NM_SETTING_GSM_PASSWORD_FLAGS "password-flags" -#define NM_SETTING_GSM_APN "apn" -#define NM_SETTING_GSM_NETWORK_ID "network-id" -#define NM_SETTING_GSM_PIN "pin" -#define NM_SETTING_GSM_PIN_FLAGS "pin-flags" -#define NM_SETTING_GSM_HOME_ONLY "home-only" -#define NM_SETTING_GSM_DEVICE_ID "device-id" -#define NM_SETTING_GSM_SIM_ID "sim-id" -#define NM_SETTING_GSM_SIM_OPERATOR_ID "sim-operator-id" -#define NM_SETTING_GSM_MTU "mtu" -#define NM_SETTING_GSM_INITIAL_EPS_BEARER_CONFIGURE "initial-eps-bearer-configure" -#define NM_SETTING_GSM_INITIAL_EPS_BEARER_APN "initial-eps-bearer-apn" +#define NM_SETTING_GSM_AUTO_CONFIG "auto-config" +#define NM_SETTING_GSM_USERNAME "username" +#define NM_SETTING_GSM_PASSWORD "password" +#define NM_SETTING_GSM_PASSWORD_FLAGS "password-flags" +#define NM_SETTING_GSM_APN "apn" +#define NM_SETTING_GSM_NETWORK_ID "network-id" +#define NM_SETTING_GSM_PIN "pin" +#define NM_SETTING_GSM_PIN_FLAGS "pin-flags" +#define NM_SETTING_GSM_HOME_ONLY "home-only" +#define NM_SETTING_GSM_DEVICE_ID "device-id" +#define NM_SETTING_GSM_SIM_ID "sim-id" +#define NM_SETTING_GSM_SIM_OPERATOR_ID "sim-operator-id" +#define NM_SETTING_GSM_MTU "mtu" +#define NM_SETTING_GSM_INITIAL_EPS_BEARER_CONFIGURE "initial-eps-bearer-configure" +#define NM_SETTING_GSM_INITIAL_EPS_BEARER_APN "initial-eps-bearer-apn" +#define NM_SETTING_GSM_INITIAL_EPS_BEARER_USERNAME "initial-eps-bearer-username" +#define NM_SETTING_GSM_INITIAL_EPS_BEARER_PASSWORD "initial-eps-bearer-password" +#define NM_SETTING_GSM_INITIAL_EPS_BEARER_PASSWORD_FLAGS "initial-eps-bearer-password-flags" +#define NM_SETTING_GSM_INITIAL_EPS_BEARER_NOAUTH "initial-eps-bearer-noauth" +#define NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_EAP "initial-eps-bearer-refuse-eap" +#define NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_PAP "initial-eps-bearer-refuse-pap" +#define NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_CHAP "initial-eps-bearer-refuse-chap" +#define NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_MSCHAP "initial-eps-bearer-refuse-mschap" +#define NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_MSCHAPV2 "initial-eps-bearer-refuse-mschapv2" /* Deprecated */ #define NM_SETTING_GSM_NUMBER "number" @@ -73,6 +82,22 @@ NM_AVAILABLE_IN_1_44 gboolean nm_setting_gsm_get_initial_eps_config(NMSettingGsm *setting); NM_AVAILABLE_IN_1_44 const char *nm_setting_gsm_get_initial_eps_apn(NMSettingGsm *setting); +NM_AVAILABLE_IN_1_52 +const char *nm_setting_gsm_get_initial_eps_username(NMSettingGsm *setting); +NM_AVAILABLE_IN_1_52 +const char *nm_setting_gsm_get_initial_eps_password(NMSettingGsm *setting); +NM_AVAILABLE_IN_1_52 +gboolean nm_setting_gsm_get_initial_eps_noauth(NMSettingGsm *setting); +NM_AVAILABLE_IN_1_52 +gboolean nm_setting_gsm_get_initial_eps_refuse_eap(NMSettingGsm *setting); +NM_AVAILABLE_IN_1_52 +gboolean nm_setting_gsm_get_initial_eps_refuse_pap(NMSettingGsm *setting); +NM_AVAILABLE_IN_1_52 +gboolean nm_setting_gsm_get_initial_eps_refuse_chap(NMSettingGsm *setting); +NM_AVAILABLE_IN_1_52 +gboolean nm_setting_gsm_get_initial_eps_refuse_mschap(NMSettingGsm *setting); +NM_AVAILABLE_IN_1_52 +gboolean nm_setting_gsm_get_initial_eps_refuse_mschapv2(NMSettingGsm *setting); NM_DEPRECATED_IN_1_16 const char *nm_setting_gsm_get_number(NMSettingGsm *setting); diff --git a/src/libnm-core-public/nm-setting-ip-config.h b/src/libnm-core-public/nm-setting-ip-config.h index 3b732882..f0a29f14 100644 --- a/src/libnm-core-public/nm-setting-ip-config.h +++ b/src/libnm-core-public/nm-setting-ip-config.h @@ -36,6 +36,23 @@ typedef enum /*< flags >*/ { NM_IP_ADDRESS_CMP_FLAGS_WITH_ATTRS = 0x1, } NMIPAddressCmpFlags; +/** + * NMSettingIPConfigRoutedDns: + * @NM_SETTING_IP_CONFIG_ROUTED_DNS_DEFAULT: use the global default value + * @NM_SETTING_IP_CONFIG_ROUTED_DNS_NO: do not add DNS routes + * @NM_SETTING_IP_CONFIG_ROUTED_DNS_YES: do add DNS routes + * + * #NMSettingIPConfigRoutedDns indicates whether routes are added + * automatically for each DNS that is associated with this connection. + * + * Since: 1.52 + */ +typedef enum { + NM_SETTING_IP_CONFIG_ROUTED_DNS_DEFAULT = -1, + NM_SETTING_IP_CONFIG_ROUTED_DNS_NO = 0, + NM_SETTING_IP_CONFIG_ROUTED_DNS_YES = 1, +} NMSettingIPConfigRoutedDns; + typedef struct NMIPAddress NMIPAddress; GType nm_ip_address_get_type(void); @@ -317,32 +334,36 @@ char *nm_ip_routing_rule_to_string(const NMIPRoutingRule *self, #define NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX 30000 -#define NM_SETTING_IP_CONFIG_METHOD "method" -#define NM_SETTING_IP_CONFIG_DNS "dns" -#define NM_SETTING_IP_CONFIG_DNS_SEARCH "dns-search" -#define NM_SETTING_IP_CONFIG_DNS_OPTIONS "dns-options" -#define NM_SETTING_IP_CONFIG_DNS_PRIORITY "dns-priority" -#define NM_SETTING_IP_CONFIG_ADDRESSES "addresses" -#define NM_SETTING_IP_CONFIG_GATEWAY "gateway" -#define NM_SETTING_IP_CONFIG_ROUTES "routes" -#define NM_SETTING_IP_CONFIG_ROUTE_METRIC "route-metric" -#define NM_SETTING_IP_CONFIG_ROUTE_TABLE "route-table" -#define NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES "ignore-auto-routes" -#define NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS "ignore-auto-dns" -#define NM_SETTING_IP_CONFIG_DHCP_HOSTNAME "dhcp-hostname" -#define NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME "dhcp-send-hostname" -#define NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS "dhcp-hostname-flags" -#define NM_SETTING_IP_CONFIG_DHCP_DSCP "dhcp-dscp" -#define NM_SETTING_IP_CONFIG_NEVER_DEFAULT "never-default" -#define NM_SETTING_IP_CONFIG_MAY_FAIL "may-fail" -#define NM_SETTING_IP_CONFIG_DAD_TIMEOUT "dad-timeout" -#define NM_SETTING_IP_CONFIG_DHCP_TIMEOUT "dhcp-timeout" -#define NM_SETTING_IP_CONFIG_REQUIRED_TIMEOUT "required-timeout" -#define NM_SETTING_IP_CONFIG_DHCP_IAID "dhcp-iaid" -#define NM_SETTING_IP_CONFIG_DHCP_REJECT_SERVERS "dhcp-reject-servers" -#define NM_SETTING_IP_CONFIG_AUTO_ROUTE_EXT_GW "auto-route-ext-gw" -#define NM_SETTING_IP_CONFIG_REPLACE_LOCAL_RULE "replace-local-rule" -#define NM_SETTING_IP_CONFIG_DHCP_SEND_RELEASE "dhcp-send-release" +#define NM_SETTING_IP_CONFIG_METHOD "method" +#define NM_SETTING_IP_CONFIG_DNS "dns" +#define NM_SETTING_IP_CONFIG_DNS_SEARCH "dns-search" +#define NM_SETTING_IP_CONFIG_DNS_OPTIONS "dns-options" +#define NM_SETTING_IP_CONFIG_DNS_PRIORITY "dns-priority" +#define NM_SETTING_IP_CONFIG_ADDRESSES "addresses" +#define NM_SETTING_IP_CONFIG_GATEWAY "gateway" +#define NM_SETTING_IP_CONFIG_ROUTES "routes" +#define NM_SETTING_IP_CONFIG_ROUTE_METRIC "route-metric" +#define NM_SETTING_IP_CONFIG_ROUTE_TABLE "route-table" +#define NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES "ignore-auto-routes" +#define NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS "ignore-auto-dns" +#define NM_SETTING_IP_CONFIG_DHCP_HOSTNAME "dhcp-hostname" +#define NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME "dhcp-send-hostname" +#define NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME_V2 "dhcp-send-hostname-v2" +#define NM_SETTING_IP_CONFIG_DHCP_HOSTNAME_FLAGS "dhcp-hostname-flags" +#define NM_SETTING_IP_CONFIG_DHCP_DSCP "dhcp-dscp" +#define NM_SETTING_IP_CONFIG_NEVER_DEFAULT "never-default" +#define NM_SETTING_IP_CONFIG_MAY_FAIL "may-fail" +#define NM_SETTING_IP_CONFIG_DAD_TIMEOUT "dad-timeout" +#define NM_SETTING_IP_CONFIG_DHCP_TIMEOUT "dhcp-timeout" +#define NM_SETTING_IP_CONFIG_REQUIRED_TIMEOUT "required-timeout" +#define NM_SETTING_IP_CONFIG_DHCP_IAID "dhcp-iaid" +#define NM_SETTING_IP_CONFIG_DHCP_REJECT_SERVERS "dhcp-reject-servers" +#define NM_SETTING_IP_CONFIG_AUTO_ROUTE_EXT_GW "auto-route-ext-gw" +#define NM_SETTING_IP_CONFIG_REPLACE_LOCAL_RULE "replace-local-rule" +#define NM_SETTING_IP_CONFIG_DHCP_SEND_RELEASE "dhcp-send-release" +#define NM_SETTING_IP_CONFIG_ROUTED_DNS "routed-dns" +#define NM_SETTING_IP_CONFIG_SHARED_DHCP_RANGE "shared-dhcp-range" +#define NM_SETTING_IP_CONFIG_SHARED_DHCP_LEASE_TIME "shared-dhcp-lease-time" /* these are not real GObject properties. */ #define NM_SETTING_IP_CONFIG_ROUTING_RULES "routing-rules" @@ -479,7 +500,8 @@ gboolean nm_setting_ip_config_get_ignore_auto_routes(NMSettingIPConfig *setting) gboolean nm_setting_ip_config_get_ignore_auto_dns(NMSettingIPConfig *setting); const char *nm_setting_ip_config_get_dhcp_hostname(NMSettingIPConfig *setting); -gboolean nm_setting_ip_config_get_dhcp_send_hostname(NMSettingIPConfig *setting); +NM_DEPRECATED_IN_1_52 +gboolean nm_setting_ip_config_get_dhcp_send_hostname(NMSettingIPConfig *setting); NM_AVAILABLE_IN_1_46 const char *nm_setting_ip_config_get_dhcp_dscp(NMSettingIPConfig *setting); @@ -512,6 +534,14 @@ NM_AVAILABLE_IN_1_44 NMTernary nm_setting_ip_config_get_replace_local_rule(NMSettingIPConfig *setting); NM_AVAILABLE_IN_1_48 NMTernary nm_setting_ip_config_get_dhcp_send_release(NMSettingIPConfig *setting); +NM_AVAILABLE_IN_1_52 +NMSettingIPConfigRoutedDns nm_setting_ip_config_get_routed_dns(NMSettingIPConfig *setting); +NM_AVAILABLE_IN_1_52 +NMTernary nm_setting_ip_config_get_dhcp_send_hostname_v2(NMSettingIPConfig *setting); +NM_AVAILABLE_IN_1_52 +const char *nm_setting_ip_config_get_shared_dhcp_range(NMSettingIPConfig *setting); +NM_AVAILABLE_IN_1_52 +int nm_setting_ip_config_get_shared_dhcp_lease_time(NMSettingIPConfig *setting); G_END_DECLS diff --git a/src/libnm-core-public/nm-setting-ip4-config.h b/src/libnm-core-public/nm-setting-ip4-config.h index 323fe14d..c40a7603 100644 --- a/src/libnm-core-public/nm-setting-ip4-config.h +++ b/src/libnm-core-public/nm-setting-ip4-config.h @@ -32,6 +32,7 @@ G_BEGIN_DECLS #define NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID "dhcp-client-id" #define NM_SETTING_IP4_CONFIG_DHCP_FQDN "dhcp-fqdn" #define NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER "dhcp-vendor-class-identifier" +#define NM_SETTING_IP4_CONFIG_DHCP_IPV6_ONLY_PREFERRED "dhcp-ipv6-only-preferred" #define NM_SETTING_IP4_CONFIG_LINK_LOCAL "link-local" /** @@ -87,7 +88,9 @@ G_BEGIN_DECLS * "link-local". * @NM_SETTING_IP4_LL_DISABLED: Disable IPv4 link-local protocol. * @NM_SETTING_IP4_LL_ENABLED: Enable the IPv4 link-local protocol regardless what other protocols - * such as DHCP or manually assigned IP addresses might be active. + * such as DHCP or manually assigned IP addresses might be active. + * @NM_SETTING_IP4_LL_FALLBACK: Since 1.52. This sets an IPv4 link-local address if no other IPv4 + * address is set, dynamically removing/re-adding it depending on DHCP leases. * * #NMSettingIP4LinkLocal values indicate whether IPv4 link-local address protocol should be enabled. * @@ -98,8 +101,26 @@ typedef enum { NM_SETTING_IP4_LL_AUTO = 1, NM_SETTING_IP4_LL_DISABLED = 2, NM_SETTING_IP4_LL_ENABLED = 3, + NM_SETTING_IP4_LL_FALLBACK = 4, } NMSettingIP4LinkLocal; +/** + * NMSettingIP4DhcpIpv6OnlyPreferred: + * @NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_DEFAULT: use the global default value + * @NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_NO: the option is disabled + * @NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_YES: the option is enabled + * + * #NMSettingIP4DhcpIpv6OnlyPreferred values specify if the "IPv6-Only Preferred" + * option (RFC 8925) for DHCPv4 is enabled. + * + * Since: 1.52 + */ +typedef enum { + NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_DEFAULT = -1, + NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_NO = 0, + NM_SETTING_IP4_DHCP_IPV6_ONLY_PREFERRED_YES = 1, +} NMSettingIP4DhcpIpv6OnlyPreferred; + typedef struct _NMSettingIP4ConfigClass NMSettingIP4ConfigClass; GType nm_setting_ip4_config_get_type(void); @@ -116,6 +137,10 @@ const char *nm_setting_ip4_config_get_dhcp_vendor_class_identifier(NMSettingIP4C NM_AVAILABLE_IN_1_42 NMSettingIP4LinkLocal nm_setting_ip4_config_get_link_local(NMSettingIP4Config *setting); +NM_AVAILABLE_IN_1_52 +NMSettingIP4DhcpIpv6OnlyPreferred +nm_setting_ip4_config_get_dhcp_ipv6_only_preferred(NMSettingIP4Config *setting); + G_END_DECLS #endif /* __NM_SETTING_IP4_CONFIG_H__ */ diff --git a/src/libnm-core-public/nm-setting-ipvlan.h b/src/libnm-core-public/nm-setting-ipvlan.h new file mode 100644 index 00000000..e332585b --- /dev/null +++ b/src/libnm-core-public/nm-setting-ipvlan.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2024 Red Hat, Inc. + */ + +#ifndef __NM_SETTING_IPVLAN_H__ +#define __NM_SETTING_IPVLAN_H__ + +#if !defined(__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) +#error "Only <NetworkManager.h> can be included directly." +#endif + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_IPVLAN (nm_setting_ipvlan_get_type()) +#define NM_SETTING_IPVLAN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_SETTING_IPVLAN, NMSettingIpvlan)) +#define NM_IS_SETTING_IPVLAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_SETTING_IPVLAN)) +#define NM_IS_SETTING_IPVLAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_SETTING_IPVLAN)) +#define NM_SETTING_IPVLAN_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_SETTING_IPVLAN, NMSettingIpvlanClass)) + +#define NM_SETTING_IPVLAN_SETTING_NAME "ipvlan" + +#define NM_SETTING_IPVLAN_PARENT "parent" +#define NM_SETTING_IPVLAN_MODE "mode" +#define NM_SETTING_IPVLAN_PRIVATE "private" +#define NM_SETTING_IPVLAN_VEPA "vepa" + +typedef struct _NMSettingIpvlanClass NMSettingIpvlanClass; + +/** + * NMSettingIpvlanMode: + * @NM_SETTING_IPVLAN_MODE_UNKNOWN: unknown/unset mode + * @NM_SETTING_IPVLAN_MODE_L2: L2 mode, device receives and responds to ARP. + * @NM_SETTING_IPVLAN_MODE_L3: L3 mode, device process only L3 traffic and above. + * @NM_SETTING_IPVLAN_MODE_L3S: L3S mode, same way as L3 mode but egress and ingress + * lands on netfilter chain. + * + * Since: 1.52 + **/ +typedef enum { + NM_SETTING_IPVLAN_MODE_UNKNOWN = 0, + NM_SETTING_IPVLAN_MODE_L2 = 1, + NM_SETTING_IPVLAN_MODE_L3 = 2, + NM_SETTING_IPVLAN_MODE_L3S = 3, + _NM_SETTING_IPVLAN_MODE_NUM, /*< skip >*/ + NM_SETTING_IPVLAN_MODE_LAST = _NM_SETTING_IPVLAN_MODE_NUM - 1, /*< skip >*/ +} NMSettingIpvlanMode; + +NM_AVAILABLE_IN_1_52 +GType nm_setting_ipvlan_get_type(void); +NM_AVAILABLE_IN_1_52 +NMSetting *nm_setting_ipvlan_new(void); + +NM_AVAILABLE_IN_1_52 +const char *nm_setting_ipvlan_get_parent(NMSettingIpvlan *setting); +NM_AVAILABLE_IN_1_52 +NMSettingIpvlanMode nm_setting_ipvlan_get_mode(NMSettingIpvlan *setting); +NM_AVAILABLE_IN_1_52 +gboolean nm_setting_ipvlan_get_private(NMSettingIpvlan *setting); +NM_AVAILABLE_IN_1_52 +gboolean nm_setting_ipvlan_get_vepa(NMSettingIpvlan *setting); + +G_END_DECLS + +#endif /* __NM_SETTING_IPVLAN_H__ */ diff --git a/src/libnm-core-public/nm-version-macros.h.in b/src/libnm-core-public/nm-version-macros.h.in index cecc1f25..d204c4df 100644 --- a/src/libnm-core-public/nm-version-macros.h.in +++ b/src/libnm-core-public/nm-version-macros.h.in @@ -76,6 +76,7 @@ #define NM_VERSION_1_46 (NM_ENCODE_VERSION(1, 46, 0)) #define NM_VERSION_1_48 (NM_ENCODE_VERSION(1, 48, 0)) #define NM_VERSION_1_50 (NM_ENCODE_VERSION(1, 50, 0)) +#define NM_VERSION_1_52 (NM_ENCODE_VERSION(1, 52, 0)) /* 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 e8e18c75..6f7e42f3 100644 --- a/src/libnm-core-public/nm-version.h +++ b/src/libnm-core-public/nm-version.h @@ -411,6 +411,20 @@ #define NM_AVAILABLE_IN_1_50 #endif +#if NM_VERSION_MIN_REQUIRED >= NM_VERSION_1_52 +#define NM_DEPRECATED_IN_1_52 G_DEPRECATED +#define NM_DEPRECATED_IN_1_52_FOR(f) G_DEPRECATED_FOR(f) +#else +#define NM_DEPRECATED_IN_1_52 +#define NM_DEPRECATED_IN_1_52_FOR(f) +#endif + +#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_52 +#define NM_AVAILABLE_IN_1_52 G_UNAVAILABLE(1, 52) +#else +#define NM_AVAILABLE_IN_1_52 +#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-core-public/nm-vpn-editor-plugin.h b/src/libnm-core-public/nm-vpn-editor-plugin.h index 4e632244..0f9801ef 100644 --- a/src/libnm-core-public/nm-vpn-editor-plugin.h +++ b/src/libnm-core-public/nm-vpn-editor-plugin.h @@ -32,9 +32,9 @@ typedef NMVpnEditorPlugin *(*NMVpnEditorPluginFactory)(GError **error); NMVpnEditorPlugin *nm_vpn_editor_plugin_factory(GError **error); #endif -/*****************************************************************************/ -/* Editor plugin interface */ -/*****************************************************************************/ +/* + * Editor plugin interface + */ #define NM_TYPE_VPN_EDITOR_PLUGIN (nm_vpn_editor_plugin_get_type()) #define NM_VPN_EDITOR_PLUGIN(obj) \ @@ -45,18 +45,20 @@ NMVpnEditorPlugin *nm_vpn_editor_plugin_factory(GError **error); /** * NMVpnEditorPluginCapability: - * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_NONE: unknown or no capability - * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT: the plugin can import new connections - * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT: the plugin can export connections - * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6: the plugin supports IPv6 addressing + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_NONE: Unknown or no capability. + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT: The plugin can import new connections. + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT: The plugin can export connections. + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6: The plugin supports IPv6 addressing. + * @NM_VPN_EDITOR_PLUGIN_CAPABILITY_NO_EDITOR: The GUI editor plugin is not available. Since: 1.52. * * Flags that indicate certain capabilities of the plugin to editor programs. **/ typedef enum /*< flags >*/ { - NM_VPN_EDITOR_PLUGIN_CAPABILITY_NONE = 0x00, - NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT = 0x01, - NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT = 0x02, - NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6 = 0x04 + NM_VPN_EDITOR_PLUGIN_CAPABILITY_NONE = 0x00, + NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT = 0x01, + NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT = 0x02, + NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6 = 0x04, + NM_VPN_EDITOR_PLUGIN_CAPABILITY_NO_EDITOR = 0x08, } NMVpnEditorPluginCapability; /* Short display name of the VPN plugin */ diff --git a/src/libnm-glib-aux/nm-dbus-aux.c b/src/libnm-glib-aux/nm-dbus-aux.c index 5c4dbc49..1be4047e 100644 --- a/src/libnm-glib-aux/nm-dbus-aux.c +++ b/src/libnm-glib-aux/nm-dbus-aux.c @@ -382,7 +382,7 @@ nm_dbus_call(GBusType bus_type, CallAsyncInfo *info; info = g_new(CallAsyncInfo, 1); - *info = (CallAsyncInfo){ + *info = (CallAsyncInfo) { .bus_name = g_strdup(bus_name), .object_path = g_strdup(object_path), .interface_name = g_strdup(interface_name), diff --git a/src/libnm-glib-aux/nm-dedup-multi.c b/src/libnm-glib-aux/nm-dedup-multi.c index cf2dba90..c80b17ce 100644 --- a/src/libnm-glib-aux/nm-dedup-multi.c +++ b/src/libnm-glib-aux/nm-dedup-multi.c @@ -54,7 +54,7 @@ nm_dedup_multi_idx_type_init(NMDedupMultiIdxType *idx_type, const NMDedupMultiId nm_assert(idx_type); nm_assert(klass); - *idx_type = (NMDedupMultiIdxType){ + *idx_type = (NMDedupMultiIdxType) { .klass = klass, .lst_idx_head = C_LIST_INIT(idx_type->lst_idx_head), }; @@ -1005,7 +1005,7 @@ nm_dedup_multi_index_new(void) NMDedupMultiIndex *self; self = g_slice_new(NMDedupMultiIndex); - *self = (NMDedupMultiIndex){ + *self = (NMDedupMultiIndex) { .ref_count = 1, .idx_entries = g_hash_table_new((GHashFunc) _dict_idx_entries_hash, (GEqualFunc) _dict_idx_entries_equal), diff --git a/src/libnm-glib-aux/nm-hash-utils.h b/src/libnm-glib-aux/nm-hash-utils.h index 703c00a4..6d7cc271 100644 --- a/src/libnm-glib-aux/nm-hash-utils.h +++ b/src/libnm-glib-aux/nm-hash-utils.h @@ -12,7 +12,7 @@ /*****************************************************************************/ #define NM_HASH_SEED_16(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af) \ - ((const guint8[16]){a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af}) + ((const guint8[16]) {a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af}) struct _nm_packed _nm_hash_seed_16_u64_data { guint64 s1; @@ -29,11 +29,11 @@ G_STATIC_ASSERT(sizeof(struct _nm_hash_seed_16_u64_data) == sizeof(guint64) * 2) * This macro takes a u64 (in host-endianness) and returns a 16 byte seed * buffer. The number will be big endian encoded, to be architecture * independent. */ -#define NM_HASH_SEED_16_U64(u64) \ - ((const guint8 *) ((gpointer) \ - & ((struct _nm_hash_seed_16_u64_data){ \ - .s1 = htobe64((u64)), \ - .s2 = 0, \ +#define NM_HASH_SEED_16_U64(u64) \ + ((const guint8 *) ((gpointer) \ + & ((struct _nm_hash_seed_16_u64_data) { \ + .s1 = htobe64((u64)), \ + .s2 = 0, \ }))) /*****************************************************************************/ @@ -212,10 +212,10 @@ nm_hash_update_str(NMHashState *state, const char *str) /* Like nm_hash_update_str(), but restricted to arrays only. nm_hash_update_str() only works * with a @str argument that cannot be NULL. If you have a string pointer, that is never NULL, use * nm_hash_update() instead. */ -#define nm_hash_update_strarr(state, str) \ - (_Generic(&(str), \ - const char(*)[sizeof(str)]: nm_hash_update_str((state), (str)), \ - char(*)[sizeof(str)]: nm_hash_update_str((state), (str)))) +#define nm_hash_update_strarr(state, str) \ + (_Generic(&(str), \ + const char(*)[sizeof(str)]: nm_hash_update_str((state), (str)), \ + char(*)[sizeof(str)]: nm_hash_update_str((state), (str)))) #else #define nm_hash_update_strarr(state, str) nm_hash_update_str((state), (str)) #endif diff --git a/src/libnm-glib-aux/nm-inet-utils.h b/src/libnm-glib-aux/nm-inet-utils.h index 65ceeb2e..489d21dd 100644 --- a/src/libnm-glib-aux/nm-inet-utils.h +++ b/src/libnm-glib-aux/nm-inet-utils.h @@ -22,10 +22,7 @@ typedef struct _NMIPAddrTyped { gint8 addr_family; } NMIPAddrTyped; -#define NM_IP_ADDR_INIT \ - { \ - .addr_ptr = { 0 } \ - } +#define NM_IP_ADDR_INIT {.addr_ptr = {0}} #define _NM_IN6ADDR_INIT(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af) \ { \ @@ -285,6 +282,7 @@ gboolean nm_ip6_addr_is_ula(const struct in6_addr *address); #define NM_IPV4LL_NETWORK ((in_addr_t) htonl(0xA9FE0000lu)) /* 169.254.0.0 */ #define NM_IPV4LL_NETMASK ((in_addr_t) htonl(0xFFFF0000lu)) /* 255.255.0.0 */ +#define NM_IPV4LL_PREFIXLEN 16 #define NM_IPV4LO_NETWORK ((in_addr_t) htonl(0x7F000000lu)) /* 127.0.0.0 */ #define NM_IPV4LO_NETMASK ((in_addr_t) htonl(0xFF000000lu)) /* 255.0.0.0 */ #define NM_IPV4LO_PREFIXLEN 8 diff --git a/src/libnm-glib-aux/nm-io-utils.c b/src/libnm-glib-aux/nm-io-utils.c index ec016ed8..9443172b 100644 --- a/src/libnm-glib-aux/nm-io-utils.c +++ b/src/libnm-glib-aux/nm-io-utils.c @@ -683,7 +683,7 @@ nm_g_subprocess_terminate_in_background(GSubprocess *subprocess, int timeout_mse main_context = g_main_context_get_thread_default(); term_data = g_slice_new(SubprocessTerminateData); - *term_data = (SubprocessTerminateData){ + *term_data = (SubprocessTerminateData) { .subprocess = g_object_ref(subprocess), .timeout_source = NULL, }; @@ -845,7 +845,7 @@ nm_sd_notify(const char *state) /* systemd calls here fd_set_sndbuf(fd, SNDBUF_SIZE) .We don't bother. */ - iovec = (struct iovec){ + iovec = (struct iovec) { .iov_base = (gpointer) state, .iov_len = strlen(state), }; diff --git a/src/libnm-glib-aux/nm-json-aux.c b/src/libnm-glib-aux/nm-json-aux.c index 6216d93c..97172726 100644 --- a/src/libnm-glib-aux/nm-json-aux.c +++ b/src/libnm-glib-aux/nm-json-aux.c @@ -230,7 +230,7 @@ _nm_json_vt_internal_load(void) fail_symbol: dlclose(&handle); - *v = (NMJsonVtInternal){}; + *v = (NMJsonVtInternal) {}; return v; } diff --git a/src/libnm-glib-aux/nm-keyfile-aux.c b/src/libnm-glib-aux/nm-keyfile-aux.c index 20a4690f..42f4f8be 100644 --- a/src/libnm-glib-aux/nm-keyfile-aux.c +++ b/src/libnm-glib-aux/nm-keyfile-aux.c @@ -485,3 +485,22 @@ nm_key_file_db_prune(NMKeyFileDB *self, } } } + +void +nm_key_file_add_group(GKeyFile *keyfile, const char *group) +{ + nm_assert(keyfile); + nm_assert(group); + + /* You can only call this function if the group doesn't exist yet. + * Because, we are about to add a dummy key, so we would have to + * be sure that the key doesn't exist. */ + nm_assert(!g_key_file_has_group(keyfile, group)); + + /* Ensure the group is present. + * There is no API for that, so add and remove a dummy key. + * For a profile it matters whether a setting is present or not, + * and we need to ensure that we persist the presence of the setting to keyfile*/ + g_key_file_set_value(keyfile, group, ".X", "1"); + g_key_file_remove_key(keyfile, group, ".X", NULL); +} diff --git a/src/libnm-glib-aux/nm-keyfile-aux.h b/src/libnm-glib-aux/nm-keyfile-aux.h index 7ada4029..50cfdfcd 100644 --- a/src/libnm-glib-aux/nm-keyfile-aux.h +++ b/src/libnm-glib-aux/nm-keyfile-aux.h @@ -58,4 +58,6 @@ void nm_key_file_db_prune(NMKeyFileDB *self, /*****************************************************************************/ +void nm_key_file_add_group(GKeyFile *keyfile, const char *group); + #endif /* __NM_KEYFILE_AUX_H__ */ diff --git a/src/libnm-glib-aux/nm-macros-internal.h b/src/libnm-glib-aux/nm-macros-internal.h index 0b39271e..151e7a4f 100644 --- a/src/libnm-glib-aux/nm-macros-internal.h +++ b/src/libnm-glib-aux/nm-macros-internal.h @@ -218,40 +218,40 @@ NM_G_ERROR_MSG(GError *error) #if _NM_CC_SUPPORT_GENERIC #define _NM_CONSTCAST_FULL_1(type, obj_expr, obj) \ (_Generic((obj_expr), \ - const void *: ((const type *) (obj)), \ - void *: ((type *) (obj)), \ - const type *: ((const type *) (obj)), \ - type *: ((type *) (obj)))) + const void *: ((const type *) (obj)), \ + void *: ((type *) (obj)), \ + const type *: ((const type *) (obj)), \ + type *: ((type *) (obj)))) #define _NM_CONSTCAST_FULL_2(type, obj_expr, obj, alias_type2) \ (_Generic((obj_expr), \ - const void *: ((const type *) (obj)), \ - void *: ((type *) (obj)), \ - const alias_type2 *: ((const type *) (obj)), \ - alias_type2 *: ((type *) (obj)), \ - const type *: ((const type *) (obj)), \ - type *: ((type *) (obj)))) + const void *: ((const type *) (obj)), \ + void *: ((type *) (obj)), \ + const alias_type2 *: ((const type *) (obj)), \ + alias_type2 *: ((type *) (obj)), \ + const type *: ((const type *) (obj)), \ + type *: ((type *) (obj)))) #define _NM_CONSTCAST_FULL_3(type, obj_expr, obj, alias_type2, alias_type3) \ (_Generic((obj_expr), \ - const void *: ((const type *) (obj)), \ - void *: ((type *) (obj)), \ - const alias_type2 *: ((const type *) (obj)), \ - alias_type2 *: ((type *) (obj)), \ - const alias_type3 *: ((const type *) (obj)), \ - alias_type3 *: ((type *) (obj)), \ - const type *: ((const type *) (obj)), \ - type *: ((type *) (obj)))) + const void *: ((const type *) (obj)), \ + void *: ((type *) (obj)), \ + const alias_type2 *: ((const type *) (obj)), \ + alias_type2 *: ((type *) (obj)), \ + const alias_type3 *: ((const type *) (obj)), \ + alias_type3 *: ((type *) (obj)), \ + const type *: ((const type *) (obj)), \ + type *: ((type *) (obj)))) #define _NM_CONSTCAST_FULL_4(type, obj_expr, obj, alias_type2, alias_type3, alias_type4) \ (_Generic((obj_expr), \ - const void *: ((const type *) (obj)), \ - void *: ((type *) (obj)), \ - const alias_type2 *: ((const type *) (obj)), \ - alias_type2 *: ((type *) (obj)), \ - const alias_type3 *: ((const type *) (obj)), \ - alias_type3 *: ((type *) (obj)), \ - const alias_type4 *: ((const type *) (obj)), \ - alias_type4 *: ((type *) (obj)), \ - const type *: ((const type *) (obj)), \ - type *: ((type *) (obj)))) + const void *: ((const type *) (obj)), \ + void *: ((type *) (obj)), \ + const alias_type2 *: ((const type *) (obj)), \ + alias_type2 *: ((type *) (obj)), \ + const alias_type3 *: ((const type *) (obj)), \ + alias_type3 *: ((type *) (obj)), \ + const alias_type4 *: ((const type *) (obj)), \ + alias_type4 *: ((type *) (obj)), \ + const type *: ((const type *) (obj)), \ + type *: ((type *) (obj)))) #define _NM_CONSTCAST_FULL_x(type, obj_expr, obj, n, ...) \ (_NM_CONSTCAST_FULL_##n(type, obj_expr, obj, ##__VA_ARGS__)) #define _NM_CONSTCAST_FULL_y(type, obj_expr, obj, n, ...) \ @@ -335,29 +335,29 @@ NM_G_ERROR_MSG(GError *error) * These macros do the cast, but they only accept a compatible input * type, otherwise they will fail compilation. */ -#define NM_CAST_STRV_MC(value) \ - (_Generic((value), \ - const char **: (const char **) (value), \ - char **: (const char **) (value), \ - void *: (const char **) (value))) -#define NM_CAST_STRV_CC(value) \ - (_Generic((value), \ - const char *const *: (const char *const *) (value), \ - const char **: (const char *const *) (value), \ - char *const *: (const char *const *) (value), \ - char **: (const char *const *) (value), \ - const void *: (const char *const *) (value), \ - void *: (const char *const *) (value))) +#define NM_CAST_STRV_MC(value) \ + (_Generic((value), \ + const char **: (const char **) (value), \ + char **: (const char **) (value), \ + void *: (const char **) (value))) +#define NM_CAST_STRV_CC(value) \ + (_Generic((value), \ + const char *const *: (const char *const *) (value), \ + const char **: (const char *const *) (value), \ + char *const *: (const char *const *) (value), \ + char **: (const char *const *) (value), \ + const void *: (const char *const *) (value), \ + void *: (const char *const *) (value))) #else #define NM_CAST_STRV_MC(value) ((const char **) (value)) #define NM_CAST_STRV_CC(value) ((const char *const *) (value)) #endif #if _NM_CC_SUPPORT_GENERIC -#define NM_PROPAGATE_CONST(test_expr, ptr) \ - (_Generic((test_expr), \ - const typeof(*(test_expr)) *: ((const typeof(*(ptr)) *) (ptr)), \ - default: (_Generic((test_expr), typeof(*(test_expr)) *: (ptr))))) +#define NM_PROPAGATE_CONST(test_expr, ptr) \ + (_Generic((test_expr), \ + const typeof(*(test_expr)) *: ((const typeof(*(ptr)) *) (ptr)), \ + default: (_Generic((test_expr), typeof(*(test_expr)) *: (ptr))))) #else #define NM_PROPAGATE_CONST(test_expr, ptr) (ptr) #endif @@ -365,8 +365,8 @@ NM_G_ERROR_MSG(GError *error) /* with the way it is implemented, the caller may or may not pass a trailing * ',' and it will work. However, this makes the macro unsuitable for initializing * an array. */ -#define NM_MAKE_STRV(...) \ - ((const char *const[(sizeof(((const char *const[]){__VA_ARGS__})) / sizeof(const char *)) \ +#define NM_MAKE_STRV(...) \ + ((const char *const[(sizeof(((const char *const[]) {__VA_ARGS__})) / sizeof(const char *)) \ + 1]){__VA_ARGS__}) /*****************************************************************************/ diff --git a/src/libnm-glib-aux/nm-prioq.c b/src/libnm-glib-aux/nm-prioq.c index e74b2b99..1b051644 100644 --- a/src/libnm-glib-aux/nm-prioq.c +++ b/src/libnm-glib-aux/nm-prioq.c @@ -57,7 +57,7 @@ nm_prioq_init(NMPrioq *q, GCompareFunc compare_func) nm_assert(q); nm_assert(compare_func); - *q = (NMPrioq){ + *q = (NMPrioq) { ._priv = { .compare_func = compare_func, @@ -76,7 +76,7 @@ nm_prioq_init_with_data(NMPrioq *q, GCompareDataFunc compare_func, gpointer comp nm_assert(q); nm_assert(compare_func); - *q = (NMPrioq){ + *q = (NMPrioq) { ._priv = { .compare_data_func = compare_func, @@ -223,7 +223,7 @@ nm_prioq_put(NMPrioq *q, void *data, unsigned *idx) k = q->_priv.n_items++; - q->_priv.items[k] = (PrioqItem){ + q->_priv.items[k] = (PrioqItem) { .data = data, .idx = idx, }; diff --git a/src/libnm-glib-aux/nm-random-utils.c b/src/libnm-glib-aux/nm-random-utils.c index bbc5536a..66c62251 100644 --- a/src/libnm-glib-aux/nm-random-utils.c +++ b/src/libnm-glib-aux/nm-random-utils.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * Copyright (C) 2017 Red Hat, Inc. + * Copyright (C) 2025 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */ #include "libnm-glib-aux/nm-default-glib-i18n-lib.h" @@ -51,420 +52,85 @@ getrandom(void *buf, size_t buflen, unsigned flags) /*****************************************************************************/ static ssize_t -_getrandom(void *buf, size_t buflen, unsigned flags) +getrandom_full(void *buf, size_t count, unsigned flags) { - static int have_getrandom = TRUE; - ssize_t l; - int errsv; - - nm_assert(buflen > 0); - - /* This calls getrandom() and either returns the positive - * success or an negative errno. ENOSYS means getrandom() - * call is not supported. That result is cached and we don't retry. */ - - if (!have_getrandom) - return -ENOSYS; - - l = getrandom(buf, buflen, flags); - if (l > 0) - return l; - if (l == 0) - return -EIO; - errsv = errno; - if (errsv == ENOSYS) - have_getrandom = FALSE; - return -errsv; -} - -static ssize_t -_getrandom_insecure(void *buf, size_t buflen) -{ - static int have_grnd_insecure = TRUE; - ssize_t l; - - /* GRND_INSECURE was added recently. We catch EINVAL - * if kernel does not support the flag (and cache it). */ - - if (!have_grnd_insecure) - return -EINVAL; - - l = _getrandom(buf, buflen, GRND_INSECURE); - - if (l == -EINVAL) - have_grnd_insecure = FALSE; - - return l; + ssize_t ret; + uint8_t *p = buf; + + do { + ret = getrandom(p, count, flags); + if (ret < 0 && errno == EINTR) + continue; + else if (ret < 0) + return ret; + p += ret; + count -= ret; + } while (count); + return 0; } -static ssize_t -_getrandom_best_effort(void *buf, size_t buflen) -{ - ssize_t l; - - /* To get best-effort bytes, we would use GRND_INSECURE (and we try that - * first). However, not all kernel versions support that, so we fallback - * to GRND_NONBLOCK. - * - * Granted, this is called from a fallback path where we have no entropy - * already, it's unlikely that GRND_NONBLOCK would succeed. Still... */ - l = _getrandom_insecure(buf, buflen); - if (l != -EINVAL) - return l; - - return _getrandom(buf, buflen, GRND_NONBLOCK); -} - -static int -_random_check_entropy(gboolean block) -{ - static gboolean seen_high_quality = FALSE; - nm_auto_close int fd = -1; - int r; - - /* We come here because getrandom() gave ENOSYS. We will fallback to /dev/urandom, - * but the caller wants to know whether we have high quality numbers. Poll - * /dev/random to find out. */ - - if (seen_high_quality) { - /* We cache the positive result. Once kernel has entropy, we will get - * good random numbers. */ - return 1; - } - - fd = open("/dev/random", O_RDONLY | O_CLOEXEC | O_NOCTTY); - if (fd < 0) - return -errno; - - r = nm_utils_fd_wait_for_event(fd, POLLIN, block ? -1 : 0); - - if (r <= 0) { - nm_assert(r < 0 || !block); - return r; - } - - nm_assert(r == 1); - seen_high_quality = TRUE; - return 1; -} - -/*****************************************************************************/ - -typedef struct _nm_packed { - uintptr_t heap_ptr; - uintptr_t stack_ptr; - gint64 now_bootime; - gint64 now_real; - pid_t pid; - pid_t ppid; - pid_t tid; - guint32 grand[16]; - guint8 auxval[16]; - guint8 getrandom_buf[20]; -} BadRandSeed; - -typedef struct _nm_packed { - guint64 counter; - union { - guint8 full[NM_UTILS_CHECKSUM_LENGTH_SHA256]; - struct { - guint8 half_1[NM_UTILS_CHECKSUM_LENGTH_SHA256 / 2]; - guint8 half_2[NM_UTILS_CHECKSUM_LENGTH_SHA256 / 2]; - }; - } sha_digest; - union { - guint8 u8[NM_UTILS_CHECKSUM_LENGTH_SHA256 / 2]; - guint32 u32[((NM_UTILS_CHECKSUM_LENGTH_SHA256 / 2) + 3) / 4]; - } rand_vals; - guint8 rand_vals_getrandom[16]; - gint64 rand_vals_timestamp; -} BadRandState; - static void -_bad_random_init_seed(BadRandSeed *seed) +dev_random_wait(void) { - const guint8 *p_at_random; - int seed_idx; - GRand *rand; - - /* g_rand_new() reads /dev/urandom too, but we already know that - * /dev/urandom fails to give us good randomness (which is why - * we hit the "bad random" code path). So this may not be as - * good as we wish, but let's hope that it it does something smart - * to give some extra entropy... */ - rand = g_rand_new(); - - /* Get some seed material from a GRand. */ - for (seed_idx = 0; seed_idx < (int) G_N_ELEMENTS(seed->grand); seed_idx++) - seed->grand[seed_idx] = g_rand_int(rand); + static bool has_waited = false; + struct pollfd random_fd = {.events = POLLIN}; + int ret; - /* Add an address from the heap and stack, maybe ASLR helps a bit? */ - seed->heap_ptr = (uintptr_t) ((gpointer) rand); - seed->stack_ptr = (uintptr_t) ((gpointer) &rand); - - g_rand_free(rand); + if (has_waited) + return; - /* Add the per-process, random number. */ - p_at_random = ((gpointer) getauxval(AT_RANDOM)); - if (p_at_random) { - G_STATIC_ASSERT(sizeof(seed->auxval) == 16); - memcpy(&seed->auxval, p_at_random, 16); + random_fd.fd = open("/dev/random", O_RDONLY); + nm_assert(random_fd.fd >= 0); + for (;;) { + ret = poll(&random_fd, 1, -1); + if (ret == 1) + break; + nm_assert(ret == -1 && errno == EINTR); } - - _getrandom_best_effort(seed->getrandom_buf, sizeof(seed->getrandom_buf)); - - seed->now_bootime = nm_utils_clock_gettime_nsec(CLOCK_BOOTTIME); - seed->now_real = g_get_real_time(); - seed->pid = getpid(); - seed->ppid = getppid(); - seed->tid = nm_utils_gettid(); + nm_close(random_fd.fd); + has_waited = true; } -static void -_bad_random_bytes(guint8 *buf, gsize n) +static ssize_t +dev_urandom_read_full(void *buf, size_t count) { - nm_auto_free_checksum GChecksum *sum = g_checksum_new(G_CHECKSUM_SHA256); - - nm_assert(n > 0); + nm_auto_close int fd = open("/dev/urandom", O_RDONLY); - /* We are in the fallback code path, where getrandom() (and /dev/urandom) failed - * to give us good randomness. Try our best. - * - * Our ability to get entropy for the CPRNG is very limited and thus the overall - * result will be bad randomness. - * - * Once we have some seed material, we combine GRand (which is not a cryptographically - * secure PRNG) with some iterative sha256 hashing. It would be nice if we had - * easy access to chacha20, but it's probably more cumbersome to fork those - * implementations than hack a bad CPRNG by using sha256 hashing. After all, this - * is fallback code to get *some* bad randomness. And with the inability to get a good - * seed, any CPRNG can only give us bad randomness. */ - - { - static BadRandState gl_state; - static GRand *gl_rand; - static GMutex gl_mutex; - NM_G_MUTEX_LOCKED(&gl_mutex); - - if (G_UNLIKELY(!gl_rand)) { - union { - BadRandSeed d_seed; - guint32 d_u32[(sizeof(BadRandSeed) + 3) / 4]; - } data = { - .d_u32 = {0}, - }; - - _bad_random_init_seed(&data.d_seed); - - gl_rand = g_rand_new_with_seed_array(data.d_u32, G_N_ELEMENTS(data.d_u32)); - - g_checksum_update(sum, (const guchar *) &data, sizeof(data)); - nm_utils_checksum_get_digest(sum, gl_state.sha_digest.full); - } - - _getrandom_best_effort(gl_state.rand_vals_getrandom, sizeof(gl_state.rand_vals_getrandom)); - - gl_state.rand_vals_timestamp = nm_utils_clock_gettime_nsec(CLOCK_BOOTTIME); - - while (TRUE) { - int i; - - gl_state.counter++; - for (i = 0; i < G_N_ELEMENTS(gl_state.rand_vals.u32); i++) - gl_state.rand_vals.u32[i] = g_rand_int(gl_rand); - g_checksum_reset(sum); - g_checksum_update(sum, (const guchar *) &gl_state, sizeof(gl_state)); - nm_utils_checksum_get_digest(sum, gl_state.sha_digest.full); - - /* gl_state.sha_digest.full and gl_state.rand_vals contain now our - * bad random values, but they are also the state for the next iteration. - * We must not directly expose that state to the caller, so XOR the values. - * - * That means, per iteration we can generate 16 bytes of bad randomness. That - * is suitable to initialize a random UUID. */ - for (i = 0; i < (int) (NM_UTILS_CHECKSUM_LENGTH_SHA256 / 2); i++) { - nm_assert(n > 0); - buf[0] = gl_state.sha_digest.half_1[i] ^ gl_state.sha_digest.half_2[i] - ^ gl_state.rand_vals.u8[i]; - buf++; - n--; - if (n == 0) - return; - } - } - } + nm_assert(fd >= 0); + return nm_utils_fd_read_loop_exact(fd, buf, count, FALSE); } -/*****************************************************************************/ - /** - * nm_random_get_bytes_full: + * nm_random_get_bytes: * @p: the buffer to fill - * @n: the number of bytes to write to @p. - * @out_high_quality: (out) (optional): whether the returned - * random bytes are of high quality. - * - * - will never block - * - will always produce some numbers, but they may not - * be of high quality. - * - Whether they are of high quality, you can know via @out_high_quality. - * - will always try hard to produce high quality numbers, and on success - * they are as good as nm_random_get_crypto_bytes(). + * @n: the number of bytes to fill */ void -nm_random_get_bytes_full(void *p, size_t n, gboolean *out_high_quality) +nm_random_get_bytes(void *p, size_t n) { - int fd; - int r; - gboolean has_high_quality; - ssize_t l; + ssize_t ret; - if (n == 0) { - NM_SET_OUT(out_high_quality, TRUE); + ret = getrandom_full(p, n, 0); + if (ret == 0) return; - } - - g_return_if_fail(p); - -again_getrandom: - l = _getrandom(p, n, GRND_NONBLOCK); - if (l > 0) { - if ((size_t) l == n) { - NM_SET_OUT(out_high_quality, TRUE); - return; - } - p = ((uint8_t *) p) + l; - n -= l; - goto again_getrandom; - } - - /* getrandom() failed. Fallback to read /dev/urandom. */ - - if (l == -ENOSYS) { - /* no support for getrandom(). */ - if (out_high_quality) { - /* The caller wants to know whether we have high quality. Poll /dev/random - * to find out. */ - has_high_quality = (_random_check_entropy(FALSE) > 0); - } else { - /* The value doesn't matter in this case. It will be unused. */ - has_high_quality = FALSE; - } - } else { - /* Any other failure of getrandom() means we don't have high quality. */ - has_high_quality = FALSE; - if (l == -EAGAIN) { - /* getrandom(GRND_NONBLOCK) failed because lack of entropy. Retry with GRND_INSECURE. */ - for (;;) { - l = _getrandom_insecure(p, n); - if (l > 0) { - if ((size_t) l == n) { - NM_SET_OUT(out_high_quality, FALSE); - return; - } - p = ((uint8_t *) p) + l; - n -= l; - continue; - } - /* Any error. Fallback to /dev/urandom. */ - break; - } - } - } - -again_open: - fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY); - if (fd < 0) { - if (errno == EINTR) - goto again_open; - } else { - r = nm_utils_fd_read_loop_exact(fd, p, n, TRUE); - nm_close(fd); - if (r >= 0) { - NM_SET_OUT(out_high_quality, has_high_quality); - return; - } - } - - /* we failed to fill the bytes reading from /dev/urandom. - * Fill the bits using our fallback approach (which obviously - * cannot give high quality random). - */ - _bad_random_bytes(p, n); - NM_SET_OUT(out_high_quality, FALSE); -} - -/*****************************************************************************/ - -/** - * nm_random_get_crypto_bytes: - * @p: the buffer to fill - * @n: the number of bytes to fill - * - * - can fail (in which case a negative number is returned - * and the output buffer is undefined). - * - will block trying to get high quality random numbers. - */ -int -nm_random_get_crypto_bytes(void *p, size_t n) -{ - nm_auto_close int fd = -1; - ssize_t l; - int r; - - if (n == 0) - return 0; - - nm_assert(p); - -again_getrandom: - l = _getrandom(p, n, 0); - if (l > 0) { - if ((size_t) l == n) - return 0; - p = (uint8_t *) p + l; - n -= l; - goto again_getrandom; - } - - if (l != -ENOSYS) { - /* We got a failure, but getrandom seems to be working in principle. We - * won't get good numbers. Fail. */ - return l; - } - - /* getrandom() failed with ENOSYS. Fallback to reading /dev/urandom. */ - - r = _random_check_entropy(TRUE); - if (r < 0) - return r; - if (r == 0) - return nm_assert_unreachable_val(-EIO); - - fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY); - if (fd < 0) - return -errno; + nm_assert(ret == 0 || (ret == -1 && errno == ENOSYS)); - return nm_utils_fd_read_loop_exact(fd, p, n, FALSE); + dev_random_wait(); + ret = dev_urandom_read_full(p, n); + nm_assert(ret == 0); } /*****************************************************************************/ guint64 -nm_random_u64_range_full(guint64 begin, guint64 end, gboolean crypto_bytes) +nm_random_u64_range(guint64 begin, guint64 end) { - gboolean bad_crypto_bytes = FALSE; - guint64 remainder; - guint64 maxvalue; - guint64 x; - guint64 m; + guint64 remainder; + guint64 maxvalue; + guint64 x; + guint64 m; - /* Returns a random #guint64 equally distributed in the range [@begin..@end-1]. - * - * The function always set errno. It either sets it to zero or to EAGAIN - * (if crypto_bytes were requested but not obtained). In any case, the function - * will always return a random number in the requested range (worst case, it's - * not crypto_bytes despite being requested). Check errno if you care. */ + /* Returns a random #guint64 equally distributed in the range [@begin..@end-1]. */ if (begin >= end) { /* systemd's random_u64_range(0) is an alias for nm_random_u64(). @@ -483,19 +149,9 @@ nm_random_u64_range_full(guint64 begin, guint64 end, gboolean crypto_bytes) maxvalue = G_MAXUINT64 - remainder; do - if (crypto_bytes) { - if (nm_random_get_crypto_bytes(&x, sizeof(x)) < 0) { - /* Cannot get good crypto numbers. We will try our best, but fail - * and set errno below. */ - crypto_bytes = FALSE; - bad_crypto_bytes = TRUE; - continue; - } - } else - nm_random_get_bytes(&x, sizeof(x)); + nm_random_get_bytes(&x, sizeof(x)); while (x >= maxvalue); out: - errno = bad_crypto_bytes ? EAGAIN : 0; return begin + (x % m); } diff --git a/src/libnm-glib-aux/nm-random-utils.h b/src/libnm-glib-aux/nm-random-utils.h index 729d71a4..43501940 100644 --- a/src/libnm-glib-aux/nm-random-utils.h +++ b/src/libnm-glib-aux/nm-random-utils.h @@ -6,15 +6,7 @@ #ifndef __NM_RANDOM_UTILS_H__ #define __NM_RANDOM_UTILS_H__ -void nm_random_get_bytes_full(void *p, size_t n, gboolean *out_high_quality); - -static inline void -nm_random_get_bytes(void *p, size_t n) -{ - nm_random_get_bytes_full(p, n, NULL); -} - -int nm_random_get_crypto_bytes(void *p, size_t n); +void nm_random_get_bytes(void *p, size_t n); static inline guint32 nm_random_u32(void) @@ -43,12 +35,6 @@ nm_random_bool(void) return ch % 2u; } -guint64 nm_random_u64_range_full(guint64 begin, guint64 end, gboolean crypto_bytes); - -static inline guint64 -nm_random_u64_range(guint64 end) -{ - return nm_random_u64_range_full(0, end, FALSE); -} +guint64 nm_random_u64_range(guint64 begin, guint64 end); #endif /* __NM_RANDOM_UTILS_H__ */ diff --git a/src/libnm-glib-aux/nm-secret-utils.h b/src/libnm-glib-aux/nm-secret-utils.h index c175bc8f..dfbaa9a9 100644 --- a/src/libnm-glib-aux/nm-secret-utils.h +++ b/src/libnm-glib-aux/nm-secret-utils.h @@ -97,19 +97,19 @@ nm_secret_ptr_clear(NMSecretPtr *secret) #define nm_auto_clear_secret_ptr nm_auto(nm_secret_ptr_clear) #define NM_SECRET_PTR_INIT() \ - ((const NMSecretPtr){ \ + ((const NMSecretPtr) { \ .len = 0, \ .ptr = NULL, \ }) -#define NM_SECRET_PTR_STATIC(_len) \ - ((const NMSecretPtr){ \ - .len = _len, \ - .ptr = ((guint8[_len]){}), \ +#define NM_SECRET_PTR_STATIC(_len) \ + ((const NMSecretPtr) { \ + .len = _len, \ + .ptr = ((guint8[_len]) {}), \ }) #define NM_SECRET_PTR_ARRAY(_arr) \ - ((const NMSecretPtr){ \ + ((const NMSecretPtr) { \ .len = G_N_ELEMENTS(_arr) * sizeof((_arr)[0]), \ .ptr = &((_arr)[0]), \ }) diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c index 25c78fd3..db730b28 100644 --- a/src/libnm-glib-aux/nm-shared-utils.c +++ b/src/libnm-glib-aux/nm-shared-utils.c @@ -32,8 +32,8 @@ G_STATIC_ASSERT(G_STRUCT_OFFSET(NMUtilsNamedValue, value_ptr) == sizeof(const ch /*****************************************************************************/ -const char _nm_hexchar_table_lower[16] = "0123456789abcdef"; -const char _nm_hexchar_table_upper[16] = "0123456789ABCDEF"; +const char _nm_hexchar_table_lower[] = "0123456789abcdef"; +const char _nm_hexchar_table_upper[] = "0123456789ABCDEF"; const void *const _NM_PTRARRAY_EMPTY[1] = {NULL}; @@ -1535,7 +1535,7 @@ _char_lookup_table_set_all(CharLookupTable *lookup, const char *candidates) static void _char_lookup_table_init(CharLookupTable *lookup, const char *candidates) { - *lookup = (CharLookupTable){ + *lookup = (CharLookupTable) { .table = {0}, }; if (candidates) @@ -3025,6 +3025,60 @@ nm_utils_buf_utf8safe_escape_cp(gconstpointer buf, gssize buflen, NMUtilsStrUtf8 return s ?: g_strdup(s_const); } +/** + * nm_utils_buf_utf8safe_escape_strv: + * @strv: an array of strings of length @strv_len + * @strv_len: the length of @strv, or -1 for a NULL terminated strv array. + * @flags: #NMUtilsStrUtf8SafeFlags flags + * @to_free: (out): return the pointer location of the newly created + * strv if copying was necessary. + * + * Ensures all strings in a strv are valid UTF-8, copying them unless they + * need to be escaped, and escaping them using nm_utils_buf_utf8safe_escape(). + * + * Returns: a strv with all its strings escaped, as valid UTF-8. All the strings + * contained within are escaped using nm_utils_buf_utf8safe_escape(). + * If no escaping was necessary it returns the input @strv. + * Otherwise, an allocated strv @to_free is returned which must be freed + * by the caller with g_strfreev(). + **/ +const char *const * +nm_utils_buf_utf8safe_escape_strv(const char *const *strv, + gssize strv_len, + NMUtilsStrUtf8SafeFlags flags, + char ***out_to_free) +{ + char **new_strv = NULL; + guint len; + + g_return_val_if_fail(strv, NULL); + g_return_val_if_fail(out_to_free, NULL); + + *out_to_free = NULL; + len = strv_len < 0 ? g_strv_length((char **) strv) : strv_len; + + for (guint i = 0; i < len; ++i) { + char *to_free_str = NULL; + + nm_utils_buf_utf8safe_escape(strv[i], -1, flags, &to_free_str); + + if (to_free_str) { + if (!new_strv) { + new_strv = nm_strv_dup(strv, len, TRUE); + } + + g_free(new_strv[i]); + new_strv[i] = to_free_str; + } + } + + if (new_strv) { + return (const char *const *) (*out_to_free = new_strv); + } + + return strv; +} + /*****************************************************************************/ const char * @@ -3677,7 +3731,7 @@ nm_utils_hashtable_cmp(const GHashTable *a, g_hash_table_iter_init(&h, hash_a); while (g_hash_table_iter_next(&h, &i_key, &i_val)) { nm_assert(i < size); - cmp_array_a[i++] = (HashTableCmpData){ + cmp_array_a[i++] = (HashTableCmpData) { .key = i_key, .val = i_val, }; @@ -3688,7 +3742,7 @@ nm_utils_hashtable_cmp(const GHashTable *a, g_hash_table_iter_init(&h, hash_b); while (g_hash_table_iter_next(&h, &i_key, &i_val)) { nm_assert(i < size); - cmp_array_b[i++] = (HashTableCmpData){ + cmp_array_b[i++] = (HashTableCmpData) { .key = i_key, .val = i_val, }; @@ -3699,7 +3753,7 @@ nm_utils_hashtable_cmp(const GHashTable *a, size, sizeof(HashTableCmpData), _hashtable_cmp_func, - &((HashTableUserData){ + &((HashTableUserData) { .cmp_keys = cmp_keys, .user_data = user_data, })); @@ -3708,7 +3762,7 @@ nm_utils_hashtable_cmp(const GHashTable *a, size, sizeof(HashTableCmpData), _hashtable_cmp_func, - &((HashTableUserData){ + &((HashTableUserData) { .cmp_keys = cmp_keys, .user_data = user_data, })); @@ -4456,7 +4510,7 @@ _nm_utils_invoke_on_idle_start(gboolean use_timeout, g_return_if_fail(callback); data = g_slice_new(InvokeOnIdleData); - *data = (InvokeOnIdleData){ + *data = (InvokeOnIdleData) { .callback = callback, .callback_user_data = callback_user_data, .cancellable = nm_g_object_ref(cancellable), @@ -5244,7 +5298,7 @@ _ctx_integ_source_prepare(GSource *source, int *out_timeout) if (G_UNLIKELY(!poll_data)) { poll_data = g_slice_new(PollData); - *poll_data = (PollData){ + *poll_data = (PollData) { .fd = fd->fd, .idx.one = i, .has_many_idx = FALSE, @@ -7262,7 +7316,7 @@ nm_utils_poll(int poll_timeout_ms, PollTaskData *poll_task_data; poll_task_data = g_slice_new(PollTaskData); - *poll_task_data = (PollTaskData){ + *poll_task_data = (PollTaskData) { .task = nm_g_task_new(NULL, cancellable, nm_utils_poll, callback, user_data), .probe_start_fcn = probe_start_fcn, .probe_finish_fcn = probe_finish_fcn, diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h index 70f1912e..4fa538e2 100644 --- a/src/libnm-glib-aux/nm-shared-utils.h +++ b/src/libnm-glib-aux/nm-shared-utils.h @@ -137,6 +137,7 @@ typedef enum { NM_LINK_TYPE_IP6GRE, NM_LINK_TYPE_IP6GRETAP, NM_LINK_TYPE_IPIP, + NM_LINK_TYPE_IPVLAN, NM_LINK_TYPE_LOOPBACK, NM_LINK_TYPE_MACSEC, NM_LINK_TYPE_MACVLAN, @@ -279,12 +280,7 @@ typedef struct _NMUtilsIPv6IfaceId { }; } NMUtilsIPv6IfaceId; -#define NM_UTILS_IPV6_IFACE_ID_INIT \ - { \ - { \ - .id = 0 \ - } \ - } +#define NM_UTILS_IPV6_IFACE_ID_INIT {{.id = 0}} /** * nm_utils_ipv6_addr_set_interface_identifier: @@ -1299,6 +1295,12 @@ const char *nm_utils_buf_utf8safe_escape(gconstpointer buf, char **to_free); char * nm_utils_buf_utf8safe_escape_cp(gconstpointer buf, gssize buflen, NMUtilsStrUtf8SafeFlags flags); + +const char *const *nm_utils_buf_utf8safe_escape_strv(const char *const *strv, + gssize strv_len, + NMUtilsStrUtf8SafeFlags flags, + char ***out_to_free); + const char * nm_utils_buf_utf8safe_escape_bytes(GBytes *bytes, NMUtilsStrUtf8SafeFlags flags, char **to_free); gconstpointer nm_utils_buf_utf8safe_unescape(const char *str, @@ -2422,28 +2424,28 @@ int nm_utils_fd_read_loop_exact(int fd, void *buf, size_t nbytes, bool do_po /*****************************************************************************/ #define NM_DEFINE_GDBUS_ARG_INFO_FULL(name_, ...) \ - ((GDBusArgInfo *) (&((const GDBusArgInfo){.ref_count = -1, .name = name_, __VA_ARGS__}))) + ((GDBusArgInfo *) (&((const GDBusArgInfo) {.ref_count = -1, .name = name_, __VA_ARGS__}))) #define NM_DEFINE_GDBUS_ARG_INFO(name_, a_signature) \ NM_DEFINE_GDBUS_ARG_INFO_FULL(name_, .signature = a_signature, ) -#define NM_DEFINE_GDBUS_ARG_INFOS(...) \ - ((GDBusArgInfo **) ((const GDBusArgInfo *[]){ \ - __VA_ARGS__ NULL, \ +#define NM_DEFINE_GDBUS_ARG_INFOS(...) \ + ((GDBusArgInfo **) ((const GDBusArgInfo *[]) { \ + __VA_ARGS__ NULL, \ })) #define NM_DEFINE_GDBUS_PROPERTY_INFO(name_, ...) \ ((GDBusPropertyInfo *) (&( \ - (const GDBusPropertyInfo){.ref_count = -1, .name = name_, __VA_ARGS__}))) + (const GDBusPropertyInfo) {.ref_count = -1, .name = name_, __VA_ARGS__}))) #define NM_DEFINE_GDBUS_PROPERTY_INFO_READABLE(name_, m_signature) \ NM_DEFINE_GDBUS_PROPERTY_INFO(name_, \ .signature = m_signature, \ .flags = G_DBUS_PROPERTY_INFO_FLAGS_READABLE, ) -#define NM_DEFINE_GDBUS_PROPERTY_INFOS(...) \ - ((GDBusPropertyInfo **) ((const GDBusPropertyInfo *[]){ \ - __VA_ARGS__ NULL, \ +#define NM_DEFINE_GDBUS_PROPERTY_INFOS(...) \ + ((GDBusPropertyInfo **) ((const GDBusPropertyInfo *[]) { \ + __VA_ARGS__ NULL, \ })) #define NM_DEFINE_GDBUS_SIGNAL_INFO_INIT(name_, ...) {.ref_count = -1, .name = name_, __VA_ARGS__} @@ -2452,9 +2454,9 @@ int nm_utils_fd_read_loop_exact(int fd, void *buf, size_t nbytes, bool do_po ((GDBusSignalInfo *) (&( \ (const GDBusSignalInfo) NM_DEFINE_GDBUS_SIGNAL_INFO_INIT(name_, __VA_ARGS__)))) -#define NM_DEFINE_GDBUS_SIGNAL_INFOS(...) \ - ((GDBusSignalInfo **) ((const GDBusSignalInfo *[]){ \ - __VA_ARGS__ NULL, \ +#define NM_DEFINE_GDBUS_SIGNAL_INFOS(...) \ + ((GDBusSignalInfo **) ((const GDBusSignalInfo *[]) { \ + __VA_ARGS__ NULL, \ })) #define NM_DEFINE_GDBUS_METHOD_INFO_INIT(name_, ...) {.ref_count = -1, .name = name_, __VA_ARGS__} @@ -2463,9 +2465,9 @@ int nm_utils_fd_read_loop_exact(int fd, void *buf, size_t nbytes, bool do_po ((GDBusMethodInfo *) (&( \ (const GDBusMethodInfo) NM_DEFINE_GDBUS_METHOD_INFO_INIT(name_, __VA_ARGS__)))) -#define NM_DEFINE_GDBUS_METHOD_INFOS(...) \ - ((GDBusMethodInfo **) ((const GDBusMethodInfo *[]){ \ - __VA_ARGS__ NULL, \ +#define NM_DEFINE_GDBUS_METHOD_INFOS(...) \ + ((GDBusMethodInfo **) ((const GDBusMethodInfo *[]) { \ + __VA_ARGS__ NULL, \ })) #define NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(name_, ...) \ @@ -2476,7 +2478,7 @@ int nm_utils_fd_read_loop_exact(int fd, void *buf, size_t nbytes, bool do_po (const GDBusInterfaceInfo) NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(name_, __VA_ARGS__)))) #define NM_DEFINE_GDBUS_INTERFACE_VTABLE(...) \ - ((GDBusInterfaceVTable *) (&((const GDBusInterfaceVTable){__VA_ARGS__}))) + ((GDBusInterfaceVTable *) (&((const GDBusInterfaceVTable) {__VA_ARGS__}))) /*****************************************************************************/ @@ -2498,7 +2500,7 @@ typedef struct _NMUtilsUserData NMUtilsUserData; NMUtilsUserData *_nm_utils_user_data_pack(int nargs, gconstpointer *args); #define nm_utils_user_data_pack(...) \ - _nm_utils_user_data_pack(NM_NARG(__VA_ARGS__), (gconstpointer[]){__VA_ARGS__}) + _nm_utils_user_data_pack(NM_NARG(__VA_ARGS__), (gconstpointer[]) {__VA_ARGS__}) void _nm_utils_user_data_unpack(NMUtilsUserData *user_data, int nargs, ...); @@ -2638,8 +2640,8 @@ int nm_utils_getpagesize(void); /*****************************************************************************/ -extern const char _nm_hexchar_table_lower[16]; -extern const char _nm_hexchar_table_upper[16]; +extern const char _nm_hexchar_table_lower[]; +extern const char _nm_hexchar_table_upper[]; static inline char nm_hexchar(int x, gboolean upper_case) diff --git a/src/libnm-glib-aux/nm-test-utils.h b/src/libnm-glib-aux/nm-test-utils.h index 2a6a5d3a..feb86301 100644 --- a/src/libnm-glib-aux/nm-test-utils.h +++ b/src/libnm-glib-aux/nm-test-utils.h @@ -1002,7 +1002,7 @@ _nmtst_add_test_func_full(const char *testpath, data = g_malloc(G_STRUCT_OFFSET(NmtstTestData, args) + (sizeof(gpointer) * (n_args + 1u) + testpath_len)); - *data = (NmtstTestData){ + *data = (NmtstTestData) { .testpath = (gpointer) &data->args[n_args + 1u], ._func_test = func_test, ._func_setup = func_setup, diff --git a/src/libnm-glib-aux/nm-uuid.h b/src/libnm-glib-aux/nm-uuid.h index b8955452..3613902f 100644 --- a/src/libnm-glib-aux/nm-uuid.h +++ b/src/libnm-glib-aux/nm-uuid.h @@ -7,13 +7,13 @@ typedef struct _NMUuid { guint8 uuid[16]; } NMUuid; -#define NM_UUID_INIT_ZERO() ((NMUuid){.uuid = {0}}) +#define NM_UUID_INIT_ZERO() ((NMUuid) {.uuid = {0}}) /* Beware, the 16 macro arguments are two hex-digits, not plain numbers. The macro * will automatically add the "0x". In particular, "09" is not an octal number, it's * 0x09. This oddity is so that the arguments look very much like the UUID in string form. */ #define NM_UUID_INIT(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) \ - ((NMUuid){ \ + ((NMUuid) { \ .uuid = {(0x##a0), \ (0x##a1), \ (0x##a2), \ diff --git a/src/libnm-glib-aux/nm-value-type.h b/src/libnm-glib-aux/nm-value-type.h index 771021da..6a0379b7 100644 --- a/src/libnm-glib-aux/nm-value-type.h +++ b/src/libnm-glib-aux/nm-value-type.h @@ -60,7 +60,7 @@ typedef union { ({ \ NMValueTypUnion *const _arg2 = (_arg); \ \ - *_arg2 = (NMValueTypUnion){ \ + *_arg2 = (NMValueTypUnion) { \ ._type = (_val), \ }; \ _arg2; \ @@ -75,7 +75,7 @@ typedef struct { ({ \ NMValueTypUnioMaybe *const _arg2 = (_arg); \ \ - *_arg2 = (NMValueTypUnioMaybe){ \ + *_arg2 = (NMValueTypUnioMaybe) { \ .has = TRUE, \ .val._type = (_val), \ }; \ diff --git a/src/libnm-glib-aux/tests/test-json-aux.c b/src/libnm-glib-aux/tests/test-json-aux.c index 32462a29..b0ca1e6d 100644 --- a/src/libnm-glib-aux/tests/test-json-aux.c +++ b/src/libnm-glib-aux/tests/test-json-aux.c @@ -88,16 +88,16 @@ test_jansson(void) CHECK_FCN(vt, json_array_get, nm_json_t * (*_f_nm)(const nm_json_t *, gsize), - json_t * (*_f_js)(const json_t *, size_t)); + json_t * (*_f_js)(const json_t *, size_t) ); CHECK_FCN(vt, json_array_size, gsize(*_f_nm)(const nm_json_t *), - size_t(*_f_js)(const json_t *)); + size_t (*_f_js)(const json_t *)); CHECK_FCN(vt, json_delete, void (*_f_nm)(nm_json_t *), void (*_f_js)(json_t *)); CHECK_FCN(vt, json_dumps, char *(*_f_nm)(const nm_json_t *, gsize), - char *(*_f_js)(const json_t *, size_t)); + char *(*_f_js)(const json_t *, size_t) ); CHECK_FCN(vt, json_false, nm_json_t * (*_f_nm)(void), json_t * (*_f_js)(void) ); CHECK_FCN(vt, json_integer, nm_json_t * (*_f_nm)(nm_json_int_t), json_t * (*_f_js)(json_int_t)); CHECK_FCN(vt, @@ -138,7 +138,7 @@ test_jansson(void) CHECK_FCN(vt, json_object_size, gsize(*_f_nm)(const nm_json_t *), - size_t(*_f_js)(const json_t *)); + size_t (*_f_js)(const json_t *)); CHECK_FCN(vt, json_string, nm_json_t * (*_f_nm)(const char *), diff --git a/src/libnm-glib-aux/tests/test-shared-general.c b/src/libnm-glib-aux/tests/test-shared-general.c index b19ac1ce..2f09a549 100644 --- a/src/libnm-glib-aux/tests/test-shared-general.c +++ b/src/libnm-glib-aux/tests/test-shared-general.c @@ -197,10 +197,7 @@ test_nm_random(void) if (begin >= end) continue; - if (begin == 0 && nmtst_get_rand_bool()) - x = nm_random_u64_range(end); - else - x = nm_random_u64_range_full(begin, end, nmtst_get_rand_bool()); + x = nm_random_u64_range(begin, end); g_assert_cmpuint(x, >=, begin); g_assert_cmpuint(x, <, end); @@ -1622,17 +1619,17 @@ test_parse_env_file(void) gs_free char *arg2 = NULL; int r; -#define env_file_1 \ - "a=a\n" \ - "a=b\n" \ - "a=b\n" \ - "a=a\n" \ - "b=b\\\n" \ - "c\n" \ - "d= d\\\n" \ - "e \\\n" \ - "f \n" \ - "g=g\\ \n" \ +#define env_file_1 \ + "a=a\n" \ + "a=b\n" \ + "a=b\n" \ + "a=a\n" \ + "b=b\\\n" \ + "c\n" \ + "d= d\\\n" \ + "e \\\n" \ + "f \n" \ + "g=g\\ \n" \ "h= ąęół\\ śćńźżµ \n" \ "i=i\\" r = nm_parse_env_file_full(env_file_1, _env_file_push_cb, &data); diff --git a/src/libnm-lldp/nm-lldp-rx.c b/src/libnm-lldp/nm-lldp-rx.c index 90414b3e..f1b5b47c 100644 --- a/src/libnm-lldp/nm-lldp-rx.c +++ b/src/libnm-lldp/nm-lldp-rx.c @@ -411,7 +411,7 @@ nm_lldp_rx_new(const NMLldpRXConfig *config) G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(NMLldpNeighbor, id) == 0); lldp_rx = g_slice_new(NMLldpRX); - *lldp_rx = (NMLldpRX){ + *lldp_rx = (NMLldpRX) { .ref_count = 1, .fd = -1, .main_context = g_main_context_ref_thread_default(), diff --git a/src/libnm-lldp/nm-lldp.h b/src/libnm-lldp/nm-lldp.h index 55e7de29..aaf87dcb 100644 --- a/src/libnm-lldp/nm-lldp.h +++ b/src/libnm-lldp/nm-lldp.h @@ -63,16 +63,8 @@ enum { | NM_LLDP_SYSTEM_CAPABILITIES_DOCSIS | NM_LLDP_SYSTEM_CAPABILITIES_CVLAN \ | NM_LLDP_SYSTEM_CAPABILITIES_SVLAN | NM_LLDP_SYSTEM_CAPABILITIES_TPMR)) -#define NM_LLDP_OUI_802_1 \ - (const uint8_t[]) \ - { \ - 0x00, 0x80, 0xc2 \ - } -#define NM_LLDP_OUI_802_3 \ - (const uint8_t[]) \ - { \ - 0x00, 0x12, 0x0f \ - } +#define NM_LLDP_OUI_802_1 (const uint8_t[]){0x00, 0x80, 0xc2} +#define NM_LLDP_OUI_802_3 (const uint8_t[]){0x00, 0x12, 0x0f} #define _SD_LLDP_OUI_IANA 0x00, 0x00, 0x5E #define NM_LLDP_OUI_IANA \ diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index f348e27c..24109568 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -865,6 +865,7 @@ static const LinkDesc link_descs[] = { [NM_LINK_TYPE_IP6GRE] = {"ip6gre", "ip6gre", NULL}, [NM_LINK_TYPE_IP6GRETAP] = {"ip6gretap", "ip6gretap", NULL}, [NM_LINK_TYPE_IPIP] = {"ipip", "ipip", NULL}, + [NM_LINK_TYPE_IPVLAN] = {"ipvlan", "ipvlan", NULL}, [NM_LINK_TYPE_LOOPBACK] = {"loopback", NULL, NULL}, [NM_LINK_TYPE_MACSEC] = {"macsec", "macsec", NULL}, [NM_LINK_TYPE_MACVLAN] = {"macvlan", "macvlan", NULL}, @@ -912,6 +913,7 @@ _link_type_from_rtnl_type(const char *name) NM_LINK_TYPE_IP6GRETAP, /* "ip6gretap" */ NM_LINK_TYPE_IP6TNL, /* "ip6tnl" */ NM_LINK_TYPE_IPIP, /* "ipip" */ + NM_LINK_TYPE_IPVLAN, /* "ipvlan" */ NM_LINK_TYPE_MACSEC, /* "macsec" */ NM_LINK_TYPE_MACVLAN, /* "macvlan" */ NM_LINK_TYPE_MACVTAP, /* "macvtap" */ @@ -2111,6 +2113,40 @@ _parse_lnk_ipip(const char *kind, struct nlattr *info_data) /*****************************************************************************/ static NMPObject * +_parse_lnk_ipvlan(const char *kind, struct nlattr *info_data) +{ + static const struct nla_policy policy[] = { + [IFLA_IPVLAN_MODE] = {.type = NLA_U16}, + [IFLA_IPVLAN_FLAGS] = {.type = NLA_U16}, + }; + NMPlatformLnkIpvlan *props; + struct nlattr *tb[G_N_ELEMENTS(policy)]; + NMPObject *obj; + + if (!info_data || !kind) + return NULL; + + if (nla_parse_nested_arr(tb, info_data, policy) < 0) + return NULL; + + if (!tb[IFLA_IPVLAN_MODE]) + return NULL; + + obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_IPVLAN, NULL); + props = &obj->lnk_ipvlan; + props->mode = nla_get_u16(tb[IFLA_IPVLAN_MODE]); + + if (tb[IFLA_IPVLAN_FLAGS]) { + props->private_flag = NM_FLAGS_HAS(nla_get_u16(tb[IFLA_IPVLAN_FLAGS]), IPVLAN_F_PRIVATE); + props->vepa = NM_FLAGS_HAS(nla_get_u16(tb[IFLA_IPVLAN_FLAGS]), IPVLAN_F_VEPA); + } + + return obj; +} + +/*****************************************************************************/ + +static NMPObject * _parse_lnk_macvlan(const char *kind, struct nlattr *info_data) { static const struct nla_policy policy[] = { @@ -2678,7 +2714,7 @@ _wireguard_update_from_allowed_ips_nla(NMPWireGuardAllowedIP *allowed_ip, struct _check_addr_or_return_val(tb, WGALLOWEDIP_A_IPADDR, addr_len, FALSE); - *allowed_ip = (NMPWireGuardAllowedIP){ + *allowed_ip = (NMPWireGuardAllowedIP) { .family = family, }; @@ -2928,7 +2964,7 @@ _wireguard_read_info(NMPlatform *platform /* used only as logging context */ /* we ignore errors, and return whatever we could successfully * parse. */ nl_recvmsgs(genl, - &((const struct nl_cb){ + &((const struct nl_cb) { .valid_cb = _wireguard_get_device_cb, .valid_arg = (gpointer) &parse_data, })); @@ -3365,7 +3401,7 @@ link_wireguard_change(NMPlatform *platform, static void _nmp_link_address_set(NMPLinkAddress *dst, const struct nlattr *nla) { - *dst = (NMPLinkAddress){ + *dst = (NMPLinkAddress) { .len = 0, }; if (nla) { @@ -3674,6 +3710,9 @@ _new_from_nl_link(NMPlatform *platform, case NM_LINK_TYPE_IPIP: lnk_data = _parse_lnk_ipip(nl_info_kind, nl_info_data); break; + case NM_LINK_TYPE_IPVLAN: + lnk_data = _parse_lnk_ipvlan(nl_info_kind, nl_info_data); + break; case NM_LINK_TYPE_MACSEC: lnk_data = _parse_lnk_macsec(nl_info_kind, nl_info_data); break; @@ -5252,6 +5291,26 @@ _nl_msg_new_link_set_linkinfo(struct nl_msg *msg, NMLinkType link_type, gconstpo NLA_PUT_U8(msg, IFLA_IPTUN_PMTUDISC, !!props->path_mtu_discovery); break; } + case NM_LINK_TYPE_IPVLAN: + { + const NMPlatformLnkIpvlan *props = extra_data; + guint16 flags = 0; + + nm_assert(props); + + if (!(data = nla_nest_start(msg, IFLA_INFO_DATA))) + goto nla_put_failure; + + if (props->private_flag) + flags |= IPVLAN_F_PRIVATE; + + if (props->vepa) + flags |= IPVLAN_F_VEPA; + + NLA_PUT_U16(msg, IFLA_IPVLAN_MODE, props->mode); + NLA_PUT_U16(msg, IFLA_IPVLAN_FLAGS, flags); + break; + } case NM_LINK_TYPE_MACSEC: { const NMPlatformLnkMacsec *props = extra_data; @@ -8156,7 +8215,7 @@ _rtnl_handle_msg(NMPlatform *platform, const struct nl_msg_lite *msg) is_del = TRUE; } - parse_nlmsg_iter = (ParseNlmsgIter){ + parse_nlmsg_iter = (ParseNlmsgIter) { .iter_more = FALSE, }; @@ -9674,13 +9733,13 @@ link_get_bridge_vlans(NMPlatform *platform, goto err; } - data = ((BridgeVlanData){ + data = ((BridgeVlanData) { .ifindex = ifindex, }); do { nle = nl_recvmsgs(sk, - &((const struct nl_cb){ + &((const struct nl_cb) { .valid_cb = get_bridge_vlans_cb, .valid_arg = &data, })); @@ -10655,6 +10714,7 @@ static int ip_route_get(NMPlatform *platform, int addr_family, gconstpointer address, + guint32 fwmark, int oif_ifindex, NMPObject **out_route) { @@ -10689,6 +10749,11 @@ ip_route_get(NMPlatform *platform, if (!_nl_addattr_l(&req.n, sizeof(req), RTA_DST, address, addr_len)) nm_assert_not_reached(); + if (fwmark != 0) { + if (!_nl_addattr_l(&req.n, sizeof(req), RTA_MARK, &fwmark, sizeof(fwmark))) + nm_assert_not_reached(); + } + if (oif_ifindex > 0) { gint32 ii = oif_ifindex; @@ -11726,12 +11791,12 @@ mptcp_addrs_dump(NMPlatform *platform) addrs = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref); - parse_data = (FetchMptcpAddrParseData){ + parse_data = (FetchMptcpAddrParseData) { .addrs = addrs, }; nl_recvmsgs(priv->sk_genl_sync, - &((const struct nl_cb){ + &((const struct nl_cb) { .valid_cb = _mptcp_addrs_dump_parse_cb, .valid_arg = (gpointer) &parse_data, })); diff --git a/src/libnm-platform/nm-netlink.c b/src/libnm-platform/nm-netlink.c index 5bbbcc84..9eb6721f 100644 --- a/src/libnm-platform/nm-netlink.c +++ b/src/libnm-platform/nm-netlink.c @@ -393,7 +393,7 @@ nlmsg_alloc(size_t len) g_return_val_if_reached(NULL); nm = g_slice_new(struct nl_msg); - *nm = (struct nl_msg){ + *nm = (struct nl_msg) { .nm_protocol = -1, .nm_size = len, .nm_nlh = g_malloc0(len), @@ -1125,7 +1125,7 @@ nl_socket_new(struct nl_sock **out_sk, nm_random_get_bytes(&seq_init, sizeof(seq_init)); sk = g_slice_new(struct nl_sock); - *sk = (struct nl_sock){ + *sk = (struct nl_sock) { .s_fd = nm_steal_fd(&fd), .s_local = { diff --git a/src/libnm-platform/nm-netlink.h b/src/libnm-platform/nm-netlink.h index efd482ad..42a81d84 100644 --- a/src/libnm-platform/nm-netlink.h +++ b/src/libnm-platform/nm-netlink.h @@ -93,19 +93,20 @@ struct nla_policy { /* static asserts that @tb and @policy are suitable arguments to nla_parse(). */ #if _NM_CC_SUPPORT_GENERIC -#define _nl_static_assert_tb(tb, policy) \ - G_STMT_START \ - { \ - G_STATIC_ASSERT_EXPR(G_N_ELEMENTS(tb) > 0); \ - \ +#define _nl_static_assert_tb(tb, policy) \ + G_STMT_START \ + { \ + G_STATIC_ASSERT_EXPR(G_N_ELEMENTS(tb) > 0); \ + \ /* We allow @policy to be either a C array or NULL. The sizeof() * must either match the expected array size or we check that * "policy" has typeof(NULL). This isn't a perfect compile time check, - * but good enough. */ \ - G_STATIC_ASSERT_EXPR(_Generic((policy), \ - typeof(NULL): 1, \ - default: (sizeof(policy) == G_N_ELEMENTS(tb) * sizeof(struct nla_policy)))); \ - } \ + * but good enough. */ \ + G_STATIC_ASSERT_EXPR( \ + _Generic((policy), \ + typeof(NULL): 1, \ + default: (sizeof(policy) == G_N_ELEMENTS(tb) * sizeof(struct nla_policy)))); \ + } \ G_STMT_END #else #define _nl_static_assert_tb(tb, policy) G_STATIC_ASSERT_EXPR(G_N_ELEMENTS(tb) > 0) diff --git a/src/libnm-platform/nm-platform-utils.c b/src/libnm-platform/nm-platform-utils.c index 3f70f5fe..15aac11c 100644 --- a/src/libnm-platform/nm-platform-utils.c +++ b/src/libnm-platform/nm-platform-utils.c @@ -431,11 +431,11 @@ ethtool_get_stringset_index(SocketHandle *shandle, int stringset_id, const char /*****************************************************************************/ static const NMEthtoolFeatureInfo _ethtool_feature_infos[_NM_ETHTOOL_ID_FEATURE_NUM] = { -#define ETHT_FEAT(eid, ...) \ - { \ - .ethtool_id = eid, \ - .n_kernel_names = NM_NARG(__VA_ARGS__), \ - .kernel_names = ((const char *const[]){__VA_ARGS__}), \ +#define ETHT_FEAT(eid, ...) \ + { \ + .ethtool_id = eid, \ + .n_kernel_names = NM_NARG(__VA_ARGS__), \ + .kernel_names = ((const char *const[]) {__VA_ARGS__}), \ } /* the order does only matter for one thing: if it happens that more than one NMEthtoolID @@ -882,7 +882,7 @@ nmp_utils_ethtool_get_coalesce(int ifindex, NMEthtoolCoalesceState *coalesce) return FALSE; } - *coalesce = (NMEthtoolCoalesceState){ + *coalesce = (NMEthtoolCoalesceState) { .s = { [_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_USECS)] = eth_data.rx_coalesce_usecs, @@ -946,7 +946,7 @@ nmp_utils_ethtool_set_coalesce(int ifindex, const NMEthtoolCoalesceState *coales g_return_val_if_fail(ifindex > 0, FALSE); g_return_val_if_fail(coalesce, FALSE); - eth_data = (struct ethtool_coalesce){ + eth_data = (struct ethtool_coalesce) { .cmd = ETHTOOL_SCOALESCE, .rx_coalesce_usecs = coalesce->s[_NM_ETHTOOL_ID_COALESCE_AS_IDX(NM_ETHTOOL_ID_COALESCE_RX_USECS)], @@ -1027,7 +1027,7 @@ nmp_utils_ethtool_get_ring(int ifindex, NMEthtoolRingState *ring) return FALSE; } - *ring = (NMEthtoolRingState){ + *ring = (NMEthtoolRingState) { .rx_pending = eth_data.rx_pending, .rx_jumbo_pending = eth_data.rx_jumbo_pending, .rx_mini_pending = eth_data.rx_mini_pending, @@ -1049,7 +1049,7 @@ nmp_utils_ethtool_set_ring(int ifindex, const NMEthtoolRingState *ring) g_return_val_if_fail(ifindex > 0, FALSE); g_return_val_if_fail(ring, FALSE); - eth_data = (struct ethtool_ringparam){ + eth_data = (struct ethtool_ringparam) { .cmd = ETHTOOL_SRINGPARAM, .rx_pending = ring->rx_pending, .rx_jumbo_pending = ring->rx_jumbo_pending, @@ -1087,7 +1087,7 @@ nmp_utils_ethtool_get_channels(int ifindex, NMEthtoolChannelsState *channels) return FALSE; } - *channels = (NMEthtoolChannelsState){ + *channels = (NMEthtoolChannelsState) { .rx = eth_data.rx_count, .tx = eth_data.tx_count, .other = eth_data.other_count, @@ -1109,7 +1109,7 @@ nmp_utils_ethtool_set_channels(int ifindex, const NMEthtoolChannelsState *channe g_return_val_if_fail(ifindex > 0, FALSE); g_return_val_if_fail(channels, FALSE); - eth_data = (struct ethtool_channels){ + eth_data = (struct ethtool_channels) { .cmd = ETHTOOL_SCHANNELS, .rx_count = channels->rx, .tx_count = channels->tx, @@ -1150,7 +1150,7 @@ nmp_utils_ethtool_get_pause(int ifindex, NMEthtoolPauseState *pause) return FALSE; } - *pause = (NMEthtoolPauseState){ + *pause = (NMEthtoolPauseState) { .autoneg = eth_data.autoneg == 1, .rx = eth_data.rx_pause == 1, .tx = eth_data.tx_pause == 1, @@ -1181,7 +1181,7 @@ nmp_utils_ethtool_get_eee(int ifindex, NMEthtoolEEEState *eee) return FALSE; } - *eee = (NMEthtoolEEEState){ + *eee = (NMEthtoolEEEState) { .enabled = eth_data.eee_enabled == 1, }; @@ -1201,7 +1201,7 @@ nmp_utils_ethtool_set_pause(int ifindex, const NMEthtoolPauseState *pause) g_return_val_if_fail(ifindex > 0, FALSE); g_return_val_if_fail(pause, FALSE); - eth_data = (struct ethtool_pauseparam){ + eth_data = (struct ethtool_pauseparam) { .cmd = ETHTOOL_SPAUSEPARAM, .autoneg = pause->autoneg ? 1 : 0, .rx_pause = pause->rx ? 1 : 0, @@ -1271,7 +1271,7 @@ nmp_utils_ethtool_get_driver_info(int ifindex, NMPUtilsEthtoolDriverInfo *data) g_return_val_if_fail(data, FALSE); drvinfo = (struct ethtool_drvinfo *) data; - *drvinfo = (struct ethtool_drvinfo){ + *drvinfo = (struct ethtool_drvinfo) { .cmd = ETHTOOL_GDRVINFO, }; return _ethtool_call_once(ifindex, drvinfo, sizeof(*drvinfo)) >= 0; @@ -1609,7 +1609,7 @@ set_link_settings_new(SocketHandle *shandle, guint nwords; guint i; - edata0 = (struct ethtool_link_settings){ + edata0 = (struct ethtool_link_settings) { .cmd = ETHTOOL_GLINKSETTINGS, .link_mode_masks_nwords = 0, }; @@ -1820,6 +1820,46 @@ nmp_utils_ethtool_set_wake_on_lan(int ifindex, return _ethtool_call_once(ifindex, &wol_info, sizeof(wol_info)) >= 0; } +gboolean +nmp_utils_ethtool_get_fec_mode(int ifindex, uint32_t *fec_mode) +{ + int r; + struct ethtool_fecparam fec_param = { + .cmd = ETHTOOL_GFECPARAM, + .fec = 0, + }; + + g_return_val_if_fail(ifindex > 0, FALSE); + + if (_ethtool_call_once(ifindex, &fec_param, sizeof(fec_param)) >= 0) { + nm_log_dbg(LOGD_PLATFORM, "ethtool[%d]: get FEC options 0x%x", ifindex, fec_param.fec); + *fec_mode = fec_param.fec; + return TRUE; + } else { + r = -NM_ERRNO_NATIVE(errno); + nm_log_dbg(LOGD_PLATFORM, + "ethtool[%d]: ETHTOOL_GFECPARAM failure get fec mode: (%s)", + ifindex, + nm_strerror_native(-r)); + return FALSE; + } +} + +gboolean +nmp_utils_ethtool_set_fec_mode(int ifindex, uint32_t fec_mode) +{ + struct ethtool_fecparam fec_param = { + .cmd = ETHTOOL_SFECPARAM, + .fec = fec_mode, + }; + + g_return_val_if_fail(ifindex > 0, FALSE); + + nm_log_dbg(LOGD_PLATFORM, "ethtool[%d]: setting FEC options 0x%x", ifindex, fec_mode); + + return _ethtool_call_once(ifindex, &fec_param, sizeof(fec_param)) >= 0; +} + /****************************************************************************** * mii *****************************************************************************/ diff --git a/src/libnm-platform/nm-platform-utils.h b/src/libnm-platform/nm-platform-utils.h index 96ac22ef..f47bcd49 100644 --- a/src/libnm-platform/nm-platform-utils.h +++ b/src/libnm-platform/nm-platform-utils.h @@ -66,6 +66,10 @@ gboolean nmp_utils_ethtool_get_eee(int ifindex, NMEthtoolEEEState *eee); gboolean nmp_utils_ethtool_set_eee(int ifindex, const NMEthtoolEEEState *eee); +gboolean nmp_utils_ethtool_get_fec_mode(int ifindex, uint32_t *fec_mode); + +gboolean nmp_utils_ethtool_set_fec_mode(int ifindex, uint32_t fec_mode); + /*****************************************************************************/ gboolean nmp_utils_mii_supports_carrier_detect(int ifindex); diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c index 658efadb..a8d34b71 100644 --- a/src/libnm-platform/nm-platform.c +++ b/src/libnm-platform/nm-platform.c @@ -1420,6 +1420,12 @@ nm_platform_link_add(NMPlatform *self, buf_p, buf_len); break; + case NM_LINK_TYPE_IPVLAN: + nm_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_ipvlan_to_string((const NMPlatformLnkIpvlan *) extra_data, + buf_p, + buf_len); + break; case NM_LINK_TYPE_MACSEC: nm_strbuf_append_str(&buf_p, &buf_len, ", "); nm_platform_lnk_macsec_to_string((const NMPlatformLnkMacsec *) extra_data, @@ -2606,6 +2612,12 @@ nm_platform_link_get_lnk_ipip(NMPlatform *self, int ifindex, const NMPlatformLin return _link_get_lnk(self, ifindex, NM_LINK_TYPE_IPIP, out_link); } +const NMPlatformLnkIpvlan * +nm_platform_link_get_lnk_ipvlan(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_IPVLAN, out_link); +} + const NMPlatformLnkMacsec * nm_platform_link_get_lnk_macsec(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { @@ -3608,6 +3620,26 @@ nm_platform_ethtool_set_features( } gboolean +nm_platform_ethtool_get_fec_mode(NMPlatform *self, int ifindex, uint32_t *fec_mode) +{ + _CHECK_SELF_NETNS(self, klass, netns, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return nmp_utils_ethtool_get_fec_mode(ifindex, fec_mode); +} + +gboolean +nm_platform_ethtool_set_fec_mode(NMPlatform *self, int ifindex, uint32_t fec_mode) +{ + _CHECK_SELF_NETNS(self, klass, netns, FALSE); + + g_return_val_if_fail(ifindex > 0, FALSE); + + return nmp_utils_ethtool_set_fec_mode(ifindex, fec_mode); +} + +gboolean nm_platform_ethtool_get_link_coalesce(NMPlatform *self, int ifindex, NMEthtoolCoalesceState *coalesce) @@ -3814,7 +3846,7 @@ nm_platform_ip4_address_add(NMPlatform *self, char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE]; NMPlatformIP4Address addr; - addr = (NMPlatformIP4Address){ + addr = (NMPlatformIP4Address) { .ifindex = ifindex, .address = address, .peer_address = peer_address, @@ -4813,7 +4845,7 @@ nm_platform_ip_address_get_prune_list(NMPlatform *self, const NMPlatformIP4Address *a4 = NMP_OBJECT_CAST_IP4_ADDRESS(obj); if (a4->address == NM_IPV4LO_ADDR1 && a4->plen == NM_IPV4LO_PREFIXLEN) { - const NMPlatformIP4Address addr = (NMPlatformIP4Address){ + const NMPlatformIP4Address addr = (NMPlatformIP4Address) { .ifindex = NM_LOOPBACK_IFINDEX, .address = NM_IPV4LO_ADDR1, .peer_address = NM_IPV4LO_ADDR1, @@ -4963,7 +4995,7 @@ nm_platform_ip_route_get_prune_list(NMPlatform *self, NMPlatformIP4Route r; if (rt->r4.network == NM_IPV4LO_ADDR1) { - r = (NMPlatformIP4Route){ + r = (NMPlatformIP4Route) { .ifindex = NM_LOOPBACK_IFINDEX, .type_coerced = nm_platform_route_type_coerce(RTN_LOCAL), .table_coerced = nm_platform_route_table_coerce(local_table), @@ -4975,7 +5007,7 @@ nm_platform_ip_route_get_prune_list(NMPlatform *self, .pref_src = NM_IPV4LO_ADDR1, }; } else { - r = (NMPlatformIP4Route){ + r = (NMPlatformIP4Route) { .ifindex = NM_LOOPBACK_IFINDEX, .type_coerced = nm_platform_route_type_coerce(RTN_LOCAL), .table_coerced = nm_platform_route_table_coerce(local_table), @@ -5624,6 +5656,7 @@ int nm_platform_ip_route_get(NMPlatform *self, int addr_family, gconstpointer address /* in_addr_t or struct in6_addr */, + guint32 fwmark, int oif_ifindex, NMPObject **out_route) { @@ -5632,21 +5665,23 @@ nm_platform_ip_route_get(NMPlatform *self, int result; char buf[NM_INET_ADDRSTRLEN]; char buf_oif[64]; + char buf_fwmark[64]; _CHECK_SELF(self, klass, FALSE); g_return_val_if_fail(address, -NME_BUG); g_return_val_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6), -NME_BUG); - _LOGT("route: get IPv%c route for: %s%s", + _LOGT("route: get IPv%c route for: %s%s%s", nm_utils_addr_family_to_char(addr_family), inet_ntop(addr_family, address, buf, sizeof(buf)), - oif_ifindex > 0 ? nm_sprintf_buf(buf_oif, " oif %d", oif_ifindex) : ""); + oif_ifindex > 0 ? nm_sprintf_buf(buf_oif, " oif %d", oif_ifindex) : "", + fwmark > 0 ? nm_sprintf_buf(buf_fwmark, " fwmark %u", fwmark) : ""); if (!klass->ip_route_get) result = -NME_PL_OPNOTSUPP; else { - result = klass->ip_route_get(self, addr_family, address, oif_ifindex, &route); + result = klass->ip_route_get(self, addr_family, address, fwmark, oif_ifindex, &route); } if (result < 0) { @@ -6704,6 +6739,21 @@ nm_platform_lnk_macvlan_to_string(const NMPlatformLnkMacvlan *lnk, char *buf, gs } const char * +nm_platform_lnk_ipvlan_to_string(const NMPlatformLnkIpvlan *lnk, char *buf, gsize len) +{ + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + g_snprintf(buf, + len, + "mode %u%s%s", + lnk->mode, + lnk->private_flag ? " private" : "", + lnk->vepa ? " vepa" : ""); + return buf; +} + +const char * nm_platform_lnk_sit_to_string(const NMPlatformLnkSit *lnk, char *buf, gsize len) { char str_local[30]; @@ -8591,6 +8641,22 @@ nm_platform_lnk_macvlan_cmp(const NMPlatformLnkMacvlan *a, const NMPlatformLnkMa } void +nm_platform_lnk_ipvlan_hash_update(const NMPlatformLnkIpvlan *obj, NMHashState *h) +{ + nm_hash_update_vals(h, obj->mode, NM_HASH_COMBINE_BOOLS(guint8, obj->private_flag, obj->vepa)); +} + +int +nm_platform_lnk_ipvlan_cmp(const NMPlatformLnkIpvlan *a, const NMPlatformLnkIpvlan *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD(a, b, mode); + NM_CMP_FIELD_UNSAFE(a, b, private_flag); + NM_CMP_FIELD_UNSAFE(a, b, vepa); + return 0; +} + +void nm_platform_lnk_sit_hash_update(const NMPlatformLnkSit *obj, NMHashState *h) { nm_hash_update_vals(h, @@ -9652,7 +9718,7 @@ nm_platform_ip4_address_generate_device_route(const NMPlatformIP4Address *addr, return NULL; } - *dst = (NMPlatformIP4Route){ + *dst = (NMPlatformIP4Route) { .ifindex = ifindex, .rt_source = NM_IP_CONFIG_SOURCE_KERNEL, .network = network_4, @@ -9999,7 +10065,7 @@ nm_platform_ip6_dadfailed_set(NMPlatform *self, if (failed) { addr = g_slice_new(IP6DadFailedAddr); - *addr = (IP6DadFailedAddr){ + *addr = (IP6DadFailedAddr) { .address = *ip6, .ifindex = ifindex, .timestamp_nsec = now_nsec, diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h index 22bf0fdb..1c8a26b3 100644 --- a/src/libnm-platform/nm-platform.h +++ b/src/libnm-platform/nm-platform.h @@ -529,9 +529,9 @@ typedef union { #undef __NMPlatformIPRoute_COMMON -#define NM_PLATFORM_IP4_ROUTE_INIT(...) (&((const NMPlatformIP4Route){__VA_ARGS__})) +#define NM_PLATFORM_IP4_ROUTE_INIT(...) (&((const NMPlatformIP4Route) {__VA_ARGS__})) -#define NM_PLATFORM_IP6_ROUTE_INIT(...) (&((const NMPlatformIP6Route){__VA_ARGS__})) +#define NM_PLATFORM_IP6_ROUTE_INIT(...) (&((const NMPlatformIP6Route) {__VA_ARGS__})) typedef struct { /* struct fib_rule_uid_range */ @@ -880,6 +880,12 @@ typedef struct { } _nm_alignas(NMPlatformObject) NMPlatformLnkIpIp; typedef struct { + guint16 mode; + bool private_flag : 1; + bool vepa : 1; +} _nm_alignas(NMPlatformObject) NMPlatformLnkIpvlan; + +typedef struct { int parent_ifindex; in_addr_t local; in_addr_t remote; @@ -1315,6 +1321,7 @@ typedef struct { int (*ip_route_get)(NMPlatform *self, int addr_family, gconstpointer address, + guint32 fwmark, int oif_ifindex, NMPObject **out_route); @@ -1935,6 +1942,27 @@ nm_platform_link_macvlan_add(NMPlatform *self, out_link); } +static inline int +nm_platform_link_ipvlan_add(NMPlatform *self, + const char *name, + int parent, + const NMPlatformLnkIpvlan *props, + const NMPlatformLink **out_link) +{ + g_return_val_if_fail(props, -NME_BUG); + g_return_val_if_fail(parent > 0, -NME_BUG); + + return nm_platform_link_add(self, + NM_LINK_TYPE_IPVLAN, + name, + parent, + NULL, + 0, + 0, + props, + out_link); +} + gboolean nm_platform_link_delete(NMPlatform *self, int ifindex); gboolean nm_platform_link_set_netns(NMPlatform *self, int ifindex, int netns_fd); @@ -2117,6 +2145,8 @@ const NMPlatformLnkMacsec * nm_platform_link_get_lnk_macsec(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkMacvlan * nm_platform_link_get_lnk_macvlan(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); +const NMPlatformLnkIpvlan * +nm_platform_link_get_lnk_ipvlan(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkMacvlan * nm_platform_link_get_lnk_macvtap(NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkSit * @@ -2404,6 +2434,7 @@ gboolean nm_platform_ip_route_flush(NMPlatform *self, int addr_family, int ifind int nm_platform_ip_route_get(NMPlatform *self, int addr_family, gconstpointer address, + guint32 fwmark, int oif_ifindex, NMPObject **out_route); @@ -2432,6 +2463,7 @@ const char *nm_platform_lnk_ipip_to_string(const NMPlatformLnkIpIp *lnk, char *b const char *nm_platform_lnk_macsec_to_string(const NMPlatformLnkMacsec *lnk, char *buf, gsize len); const char * nm_platform_lnk_macvlan_to_string(const NMPlatformLnkMacvlan *lnk, char *buf, gsize len); +const char *nm_platform_lnk_ipvlan_to_string(const NMPlatformLnkIpvlan *lnk, char *buf, gsize len); const char *nm_platform_lnk_sit_to_string(const NMPlatformLnkSit *lnk, char *buf, gsize len); const char *nm_platform_lnk_tun_to_string(const NMPlatformLnkTun *lnk, char *buf, gsize len); const char *nm_platform_lnk_vlan_to_string(const NMPlatformLnkVlan *lnk, char *buf, gsize len); @@ -2484,6 +2516,7 @@ int nm_platform_lnk_infiniband_cmp(const NMPlatformLnkInfiniband *a, int nm_platform_lnk_ip6tnl_cmp(const NMPlatformLnkIp6Tnl *a, const NMPlatformLnkIp6Tnl *b); int nm_platform_lnk_ipip_cmp(const NMPlatformLnkIpIp *a, const NMPlatformLnkIpIp *b); int nm_platform_lnk_macsec_cmp(const NMPlatformLnkMacsec *a, const NMPlatformLnkMacsec *b); +int nm_platform_lnk_ipvlan_cmp(const NMPlatformLnkIpvlan *a, const NMPlatformLnkIpvlan *b); int nm_platform_lnk_macvlan_cmp(const NMPlatformLnkMacvlan *a, const NMPlatformLnkMacvlan *b); int nm_platform_lnk_sit_cmp(const NMPlatformLnkSit *a, const NMPlatformLnkSit *b); int nm_platform_lnk_tun_cmp(const NMPlatformLnkTun *a, const NMPlatformLnkTun *b); @@ -2558,6 +2591,7 @@ void nm_platform_lnk_ip6tnl_hash_update(const NMPlatformLnkIp6Tnl *obj, NMHashSt void nm_platform_lnk_ipip_hash_update(const NMPlatformLnkIpIp *obj, NMHashState *h); void nm_platform_lnk_macsec_hash_update(const NMPlatformLnkMacsec *obj, NMHashState *h); void nm_platform_lnk_macvlan_hash_update(const NMPlatformLnkMacvlan *obj, NMHashState *h); +void nm_platform_lnk_ipvlan_hash_update(const NMPlatformLnkIpvlan *obj, NMHashState *h); void nm_platform_lnk_sit_hash_update(const NMPlatformLnkSit *obj, NMHashState *h); void nm_platform_lnk_tun_hash_update(const NMPlatformLnkTun *obj, NMHashState *h); void nm_platform_lnk_vlan_hash_update(const NMPlatformLnkVlan *obj, NMHashState *h); @@ -2621,6 +2655,10 @@ gboolean nm_platform_ethtool_set_channels(NMPlatform *self, int ifindex, const NMEthtoolChannelsState *channels); +gboolean nm_platform_ethtool_get_fec_mode(NMPlatform *self, int ifindex, uint32_t *fec_mode); + +gboolean nm_platform_ethtool_set_fec_mode(NMPlatform *self, int ifindex, uint32_t fec_mode); + gboolean nm_platform_ethtool_get_link_pause(NMPlatform *self, int ifindex, NMEthtoolPauseState *pause); @@ -2657,7 +2695,7 @@ void nm_platform_ip6_dadfailed_set(NMPlatform *self, static inline NMPlatformIP4Address * nm_platform_ip4_address_init_loopback_addr1(NMPlatformIP4Address *a) { - *a = ((NMPlatformIP4Address){ + *a = ((NMPlatformIP4Address) { .address = NM_IPV4LO_ADDR1, .peer_address = NM_IPV4LO_ADDR1, .ifindex = NM_LOOPBACK_IFINDEX, @@ -2669,7 +2707,7 @@ nm_platform_ip4_address_init_loopback_addr1(NMPlatformIP4Address *a) static inline NMPlatformIP6Address * nm_platform_ip6_address_init_loopback(NMPlatformIP6Address *a) { - *a = ((NMPlatformIP6Address){ + *a = ((NMPlatformIP6Address) { .address = IN6ADDR_LOOPBACK_INIT, .ifindex = NM_LOOPBACK_IFINDEX, .plen = 128, diff --git a/src/libnm-platform/nmp-base.h b/src/libnm-platform/nmp-base.h index 3784a78e..f6656296 100644 --- a/src/libnm-platform/nmp-base.h +++ b/src/libnm-platform/nmp-base.h @@ -174,6 +174,7 @@ typedef enum _nm_packed { NMP_OBJECT_TYPE_LNK_IP6GRE, NMP_OBJECT_TYPE_LNK_IP6GRETAP, NMP_OBJECT_TYPE_LNK_IPIP, + NMP_OBJECT_TYPE_LNK_IPVLAN, NMP_OBJECT_TYPE_LNK_MACSEC, NMP_OBJECT_TYPE_LNK_MACVLAN, NMP_OBJECT_TYPE_LNK_MACVTAP, diff --git a/src/libnm-platform/nmp-global-tracker.c b/src/libnm-platform/nmp-global-tracker.c index b06e9fe5..8caa70ef 100644 --- a/src/libnm-platform/nmp-global-tracker.c +++ b/src/libnm-platform/nmp-global-tracker.c @@ -422,7 +422,7 @@ nmp_global_tracker_track(NMPGlobalTracker *self, if (!track_data) { track_data = g_slice_new(TrackData); - *track_data = (TrackData){ + *track_data = (TrackData) { .obj = nm_dedup_multi_index_obj_intern(nm_platform_get_multi_idx(self->platform), p_obj_stack), .user_tag = user_tag, @@ -435,7 +435,7 @@ nmp_global_tracker_track(NMPGlobalTracker *self, obj_data = g_hash_table_lookup(self->by_obj, &track_data->obj); if (!obj_data) { obj_data = g_slice_new(TrackObjData); - *obj_data = (TrackObjData){ + *obj_data = (TrackObjData) { .obj = nmp_object_ref(track_data->obj), .obj_lst_head = C_LIST_INIT(obj_data->obj_lst_head), .config_state = CONFIG_STATE_NONE, @@ -448,7 +448,7 @@ nmp_global_tracker_track(NMPGlobalTracker *self, user_tag_data = g_hash_table_lookup(self->by_user_tag, &track_data->user_tag); if (!user_tag_data) { user_tag_data = g_slice_new(TrackUserTagData); - *user_tag_data = (TrackUserTagData){ + *user_tag_data = (TrackUserTagData) { .user_tag = user_tag, .user_tag_lst_head = C_LIST_INIT(user_tag_data->user_tag_lst_head), }; @@ -651,7 +651,7 @@ nmp_global_tracker_mptcp_addr_init_for_ifindex(NMPlatformMptcpAddr *addr, int if nm_assert(addr); nm_assert(ifindex > 0); - *addr = (NMPlatformMptcpAddr){ + *addr = (NMPlatformMptcpAddr) { .ifindex = ifindex, .addr_family = AF_UNSPEC, }; @@ -776,7 +776,7 @@ nmp_global_tracker_sync_mptcp_addrs(NMPGlobalTracker *self, gboolean reapply) entries = g_array_new(FALSE, FALSE, sizeof(MptcpSyncData)); g_array_append_val(entries, - ((const MptcpSyncData){ + ((const MptcpSyncData) { .obj_data = obj_data, .td_best = td_best, })); @@ -1158,7 +1158,7 @@ nmp_global_tracker_track_rule_default(NMPGlobalTracker *self, if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET)) { nmp_global_tracker_track_local_rule(self, addr_family, track_priority, user_tag, NULL); nmp_global_tracker_track_rule(self, - &((NMPlatformRoutingRule){ + &((NMPlatformRoutingRule) { .addr_family = AF_INET, .priority = 32766, .table = RT_TABLE_MAIN, @@ -1169,7 +1169,7 @@ nmp_global_tracker_track_rule_default(NMPGlobalTracker *self, user_tag, NULL); nmp_global_tracker_track_rule(self, - &((NMPlatformRoutingRule){ + &((NMPlatformRoutingRule) { .addr_family = AF_INET, .priority = 32767, .table = RT_TABLE_DEFAULT, @@ -1183,7 +1183,7 @@ nmp_global_tracker_track_rule_default(NMPGlobalTracker *self, if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET6)) { nmp_global_tracker_track_local_rule(self, addr_family, track_priority, user_tag, NULL); nmp_global_tracker_track_rule(self, - &((NMPlatformRoutingRule){ + &((NMPlatformRoutingRule) { .addr_family = AF_INET6, .priority = 32766, .table = RT_TABLE_MAIN, @@ -1209,7 +1209,7 @@ nmp_global_tracker_track_local_rule(NMPGlobalTracker *self, if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET)) { nmp_global_tracker_track_rule(self, - &((NMPlatformRoutingRule){ + &((NMPlatformRoutingRule) { .addr_family = AF_INET, .priority = 0, .table = RT_TABLE_LOCAL, @@ -1222,7 +1222,7 @@ nmp_global_tracker_track_local_rule(NMPGlobalTracker *self, } if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET6)) { nmp_global_tracker_track_rule(self, - &((NMPlatformRoutingRule){ + &((NMPlatformRoutingRule) { .addr_family = AF_INET6, .priority = 0, .table = RT_TABLE_LOCAL, @@ -1247,7 +1247,7 @@ nmp_global_tracker_new(NMPlatform *platform) G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(TrackUserTagData, user_tag) == 0); self = g_slice_new(NMPGlobalTracker); - *self = (NMPGlobalTracker){ + *self = (NMPGlobalTracker) { .ref_count = 1, .platform = g_object_ref(platform), .by_data = diff --git a/src/libnm-platform/nmp-netns.c b/src/libnm-platform/nmp-netns.c index c18f67ab..a0de8366 100644 --- a/src/libnm-platform/nmp-netns.c +++ b/src/libnm-platform/nmp-netns.c @@ -265,7 +265,7 @@ _stack_push(GArray *netns_stack, NMPNetns *netns, int ns_types) nm_assert(!NM_FLAGS_ANY(ns_types, ~_CLONE_NS_ALL)); info = nm_g_array_append_new(netns_stack, NetnsInfo); - *info = (NetnsInfo){ + *info = (NetnsInfo) { .netns = g_object_ref(netns), .ns_types = ns_types, .count = 1, diff --git a/src/libnm-platform/nmp-object.c b/src/libnm-platform/nmp-object.c index 1fdaa275..f41cc95a 100644 --- a/src/libnm-platform/nmp-object.c +++ b/src/libnm-platform/nmp-object.c @@ -3565,6 +3565,18 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_ipip_hash_update, .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_ipip_cmp, }, + [NMP_OBJECT_TYPE_LNK_IPVLAN - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_IPVLAN, + .sizeof_data = sizeof(NMPObjectLnkIpvlan), + .sizeof_public = sizeof(NMPlatformLnkIpvlan), + .obj_type_name = "ipvlan", + .lnk_link_type = NM_LINK_TYPE_IPVLAN, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_ipvlan_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_ipvlan_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_ipvlan_cmp, + }, [NMP_OBJECT_TYPE_LNK_MACSEC - 1] = { .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), diff --git a/src/libnm-platform/nmp-object.h b/src/libnm-platform/nmp-object.h index cd1793d4..b526fc3b 100644 --- a/src/libnm-platform/nmp-object.h +++ b/src/libnm-platform/nmp-object.h @@ -271,6 +271,10 @@ typedef struct { } NMPObjectLnkIpIp; typedef struct { + NMPlatformLnkIpvlan _public; +} NMPObjectLnkIpvlan; + +typedef struct { NMPlatformLnkMacsec _public; } NMPObjectLnkMacsec; @@ -394,6 +398,9 @@ struct _NMPObject { NMPlatformLnkIp6Tnl lnk_ip6tnl; NMPObjectLnkIp6Tnl _lnk_ip6tnl; + NMPlatformLnkIpvlan lnk_ipvlan; + NMPObjectLnkIpvlan _lnk_ipvlan; + NMPlatformLnkMacsec lnk_macsec; NMPObjectLnkMacsec _lnk_macsec; @@ -544,6 +551,7 @@ _NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX(NMPObjectType obj_type) case NMP_OBJECT_TYPE_LNK_IP6GRE: case NMP_OBJECT_TYPE_LNK_IP6GRETAP: case NMP_OBJECT_TYPE_LNK_IPIP: + case NMP_OBJECT_TYPE_LNK_IPVLAN: case NMP_OBJECT_TYPE_LNK_MACSEC: case NMP_OBJECT_TYPE_LNK_MACVLAN: case NMP_OBJECT_TYPE_LNK_MACVTAP: diff --git a/src/libnm-platform/nmp-plobj.h b/src/libnm-platform/nmp-plobj.h index ad18573f..7760c02c 100644 --- a/src/libnm-platform/nmp-plobj.h +++ b/src/libnm-platform/nmp-plobj.h @@ -156,9 +156,9 @@ typedef enum { NMPlatformIP4Address, \ NMPlatformIP6Address) -#define NM_PLATFORM_IP4_ADDRESS_INIT(...) (&((const NMPlatformIP4Address){__VA_ARGS__})) +#define NM_PLATFORM_IP4_ADDRESS_INIT(...) (&((const NMPlatformIP4Address) {__VA_ARGS__})) -#define NM_PLATFORM_IP6_ADDRESS_INIT(...) (&((const NMPlatformIP6Address){__VA_ARGS__})) +#define NM_PLATFORM_IP6_ADDRESS_INIT(...) (&((const NMPlatformIP6Address) {__VA_ARGS__})) /*****************************************************************************/ @@ -195,6 +195,15 @@ nm_platform_ip4_address_cmp_full(const NMPlatformIP4Address *a, const NMPlatform return nm_platform_ip4_address_cmp(a, b, NM_PLATFORM_IP_ADDRESS_CMP_TYPE_FULL); } +static inline gboolean +nm_platform_ip4_address_is_link_local(const NMPlatformIP4Address *a) +{ + nm_assert(a); + + return nm_ip4_addr_is_link_local(a->address) && a->plen == NM_IPV4LL_PREFIXLEN + && a->address == a->peer_address; +} + void nm_platform_ip6_address_hash_update(const NMPlatformIP6Address *obj, NMHashState *h); int nm_platform_ip6_address_cmp(const NMPlatformIP6Address *a, diff --git a/src/libnm-platform/tests/test-nm-platform.c b/src/libnm-platform/tests/test-nm-platform.c index 37707875..22148f8c 100644 --- a/src/libnm-platform/tests/test-nm-platform.c +++ b/src/libnm-platform/tests/test-nm-platform.c @@ -198,12 +198,12 @@ test_nmp_utils_bridge_vlans_normalize(void) guint vlans_len; /* Single one is unmodified */ - vlans[0] = (NMPlatformBridgeVlan){ + vlans[0] = (NMPlatformBridgeVlan) { .vid_start = 1, .vid_end = 10, .untagged = TRUE, }; - expect[0] = (NMPlatformBridgeVlan){ + expect[0] = (NMPlatformBridgeVlan) { .vid_start = 1, .vid_end = 10, .untagged = TRUE, @@ -214,61 +214,61 @@ test_nmp_utils_bridge_vlans_normalize(void) g_assert(nmp_utils_bridge_normalized_vlans_equal(vlans, vlans_len, expect, vlans_len)); /* Not merged if flags are different */ - vlans[0] = (NMPlatformBridgeVlan){ + vlans[0] = (NMPlatformBridgeVlan) { .vid_start = 1, .vid_end = 10, .untagged = TRUE, }; - vlans[1] = (NMPlatformBridgeVlan){ + vlans[1] = (NMPlatformBridgeVlan) { .vid_start = 11, .vid_end = 11, .pvid = TRUE, }; - vlans[2] = (NMPlatformBridgeVlan){ + vlans[2] = (NMPlatformBridgeVlan) { .vid_start = 20, .vid_end = 25, }; - vlans[3] = (NMPlatformBridgeVlan){ + vlans[3] = (NMPlatformBridgeVlan) { .vid_start = 26, .vid_end = 30, .untagged = TRUE, }; - vlans[4] = (NMPlatformBridgeVlan){ + vlans[4] = (NMPlatformBridgeVlan) { .vid_start = 40, .vid_end = 40, .untagged = TRUE, }; - vlans[5] = (NMPlatformBridgeVlan){ + vlans[5] = (NMPlatformBridgeVlan) { .vid_start = 40, .vid_end = 40, .untagged = TRUE, .pvid = TRUE, }; - expect[0] = (NMPlatformBridgeVlan){ + expect[0] = (NMPlatformBridgeVlan) { .vid_start = 1, .vid_end = 10, .untagged = TRUE, }; - expect[1] = (NMPlatformBridgeVlan){ + expect[1] = (NMPlatformBridgeVlan) { .vid_start = 11, .vid_end = 11, .pvid = TRUE, }; - expect[2] = (NMPlatformBridgeVlan){ + expect[2] = (NMPlatformBridgeVlan) { .vid_start = 20, .vid_end = 25, }; - expect[3] = (NMPlatformBridgeVlan){ + expect[3] = (NMPlatformBridgeVlan) { .vid_start = 26, .vid_end = 30, .untagged = TRUE, }; - expect[4] = (NMPlatformBridgeVlan){ + expect[4] = (NMPlatformBridgeVlan) { .vid_start = 40, .vid_end = 40, .untagged = TRUE, }; - expect[5] = (NMPlatformBridgeVlan){ + expect[5] = (NMPlatformBridgeVlan) { .vid_start = 40, .vid_end = 40, .untagged = TRUE, @@ -280,22 +280,22 @@ test_nmp_utils_bridge_vlans_normalize(void) g_assert(nmp_utils_bridge_normalized_vlans_equal(vlans, vlans_len, expect, vlans_len)); /* Overlapping and contiguous ranges are merged */ - vlans[0] = (NMPlatformBridgeVlan){ + vlans[0] = (NMPlatformBridgeVlan) { .vid_start = 1, .vid_end = 10, .untagged = TRUE, }; - vlans[1] = (NMPlatformBridgeVlan){ + vlans[1] = (NMPlatformBridgeVlan) { .vid_start = 11, .vid_end = 20, .untagged = TRUE, }; - vlans[2] = (NMPlatformBridgeVlan){ + vlans[2] = (NMPlatformBridgeVlan) { .vid_start = 19, .vid_end = 30, .untagged = TRUE, }; - expect[0] = (NMPlatformBridgeVlan){ + expect[0] = (NMPlatformBridgeVlan) { .vid_start = 1, .vid_end = 30, .untagged = TRUE, @@ -305,42 +305,42 @@ test_nmp_utils_bridge_vlans_normalize(void) g_assert(vlans_len == 1); g_assert(nmp_utils_bridge_normalized_vlans_equal(vlans, vlans_len, expect, vlans_len)); - vlans[0] = (NMPlatformBridgeVlan){ + vlans[0] = (NMPlatformBridgeVlan) { .vid_start = 20, .vid_end = 20, }; - vlans[1] = (NMPlatformBridgeVlan){ + vlans[1] = (NMPlatformBridgeVlan) { .vid_start = 4, .vid_end = 4, .pvid = TRUE, }; - vlans[2] = (NMPlatformBridgeVlan){ + vlans[2] = (NMPlatformBridgeVlan) { .vid_start = 33, .vid_end = 33, }; - vlans[3] = (NMPlatformBridgeVlan){ + vlans[3] = (NMPlatformBridgeVlan) { .vid_start = 100, .vid_end = 100, .untagged = TRUE, }; - vlans[4] = (NMPlatformBridgeVlan){ + vlans[4] = (NMPlatformBridgeVlan) { .vid_start = 34, .vid_end = 40, }; - vlans[5] = (NMPlatformBridgeVlan){ + vlans[5] = (NMPlatformBridgeVlan) { .vid_start = 21, .vid_end = 32, }; - expect[0] = (NMPlatformBridgeVlan){ + expect[0] = (NMPlatformBridgeVlan) { .vid_start = 4, .vid_end = 4, .pvid = TRUE, }; - expect[1] = (NMPlatformBridgeVlan){ + expect[1] = (NMPlatformBridgeVlan) { .vid_start = 20, .vid_end = 40, }; - expect[2] = (NMPlatformBridgeVlan){ + expect[2] = (NMPlatformBridgeVlan) { .vid_start = 100, .vid_end = 100, .untagged = TRUE, @@ -364,7 +364,7 @@ test_nmp_utils_bridge_normalized_vlans_equal(void) g_assert(nmp_utils_bridge_normalized_vlans_equal(NULL, 0, b, 0)); /* One empty, other not */ - a[0] = (NMPlatformBridgeVlan){ + a[0] = (NMPlatformBridgeVlan) { .vid_start = 1, .vid_end = 10, .untagged = TRUE, @@ -373,22 +373,22 @@ test_nmp_utils_bridge_normalized_vlans_equal(void) g_assert(!nmp_utils_bridge_normalized_vlans_equal(NULL, 0, a, 1)); /* Equal range + VLAN */ - a[0] = (NMPlatformBridgeVlan){ + a[0] = (NMPlatformBridgeVlan) { .vid_start = 1, .vid_end = 10, .untagged = TRUE, }; - a[1] = (NMPlatformBridgeVlan){ + a[1] = (NMPlatformBridgeVlan) { .vid_start = 11, .vid_end = 11, .pvid = TRUE, }; - b[0] = (NMPlatformBridgeVlan){ + b[0] = (NMPlatformBridgeVlan) { .vid_start = 1, .vid_end = 10, .untagged = TRUE, }; - b[1] = (NMPlatformBridgeVlan){ + b[1] = (NMPlatformBridgeVlan) { .vid_start = 11, .vid_end = 11, .pvid = TRUE, @@ -402,12 +402,12 @@ test_nmp_utils_bridge_normalized_vlans_equal(void) g_assert(!nmp_utils_bridge_normalized_vlans_equal(b, 2, a, 2)); /* Different ranges */ - a[0] = (NMPlatformBridgeVlan){ + a[0] = (NMPlatformBridgeVlan) { .vid_start = 1, .vid_end = 30, .untagged = TRUE, }; - b[0] = (NMPlatformBridgeVlan){ + b[0] = (NMPlatformBridgeVlan) { .vid_start = 1, .vid_end = 29, .untagged = TRUE, diff --git a/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c b/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c index 3c00898a..020c054b 100644 --- a/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c +++ b/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c @@ -689,7 +689,7 @@ nl80211_wiphy_info_handler(const struct nl_msg *msg, void *arg) } f = &info->freqs[info->num_freqs]; - *f = (Nl80211Freq){ + *f = (Nl80211Freq) { .freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]), .disabled = !!tb_freq[NL80211_FREQUENCY_ATTR_DISABLED], .no_ir = !!tb_freq[NL80211_FREQUENCY_ATTR_NO_IR], diff --git a/src/libnm-std-aux/nm-std-aux.h b/src/libnm-std-aux/nm-std-aux.h index bbd08dd7..7f08de5d 100644 --- a/src/libnm-std-aux/nm-std-aux.h +++ b/src/libnm-std-aux/nm-std-aux.h @@ -83,6 +83,8 @@ /*****************************************************************************/ +/* Reason for double application is described here + * https://gcc.gnu.org/onlinedocs/gcc-4.8.5/cpp/Stringification.html */ #define NM_STRINGIFY_ARG(contents) #contents #define NM_STRINGIFY(macro_or_string) NM_STRINGIFY_ARG(macro_or_string) diff --git a/src/libnm-systemd-core/nm-sd.c b/src/libnm-systemd-core/nm-sd.c index b512e3fc..aecbdf94 100644 --- a/src/libnm-systemd-core/nm-sd.c +++ b/src/libnm-systemd-core/nm-sd.c @@ -70,7 +70,7 @@ event_create_source(sd_event *event) source->event = is_default_event ? g_steal_pointer(&event) : sd_event_ref(event); - source->pollfd = (GPollFD){ + source->pollfd = (GPollFD) { .fd = sd_event_get_fd(source->event), .events = G_IO_IN | G_IO_HUP | G_IO_ERR, }; diff --git a/src/libnm-systemd-core/src/libsystemd-network/dhcp-duid-internal.h b/src/libnm-systemd-core/src/libsystemd-network/dhcp-duid-internal.h index f8bc15c4..0d3d6b5c 100644 --- a/src/libnm-systemd-core/src/libsystemd-network/dhcp-duid-internal.h +++ b/src/libnm-systemd-core/src/libsystemd-network/dhcp-duid-internal.h @@ -73,7 +73,7 @@ static inline bool duid_data_size_is_valid(size_t size) { return size >= MIN_DUID_DATA_LEN && size <= MAX_DUID_DATA_LEN; } -const char *duid_type_to_string(DUIDType t) _const_; +const char* duid_type_to_string(DUIDType t) _const_; int dhcp_duid_to_string_internal(uint16_t type, const void *data, size_t data_size, char **ret); int dhcp_identifier_set_iaid( diff --git a/src/libnm-systemd-core/src/libsystemd-network/dhcp6-internal.h b/src/libnm-systemd-core/src/libsystemd-network/dhcp6-internal.h index 3fbfc028..ecd62ea8 100644 --- a/src/libnm-systemd-core/src/libsystemd-network/dhcp6-internal.h +++ b/src/libnm-systemd-core/src/libsystemd-network/dhcp6-internal.h @@ -84,9 +84,8 @@ struct sd_dhcp6_client { bool send_release; }; -int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *address); -int dhcp6_network_send_udp_socket(int s, struct in6_addr *address, - const void *packet, size_t len); +int dhcp6_network_bind_udp_socket(int ifindex, const struct in6_addr *address); +int dhcp6_network_send_udp_socket(int s, const struct in6_addr *address, const void *packet, size_t len); int dhcp6_client_send_message(sd_dhcp6_client *client); int dhcp6_client_set_transaction_id(sd_dhcp6_client *client, uint32_t transaction_id); diff --git a/src/libnm-systemd-core/src/libsystemd-network/dhcp6-lease-internal.h b/src/libnm-systemd-core/src/libsystemd-network/dhcp6-lease-internal.h index e76a108f..60cd84f2 100644 --- a/src/libnm-systemd-core/src/libsystemd-network/dhcp6-lease-internal.h +++ b/src/libnm-systemd-core/src/libsystemd-network/dhcp6-lease-internal.h @@ -8,6 +8,7 @@ #include <inttypes.h> #include "sd-dhcp6-lease.h" +#include "dns-resolver-internal.h" #include "dhcp6-option.h" #include "dhcp6-protocol.h" @@ -38,6 +39,8 @@ struct sd_dhcp6_lease { struct in6_addr *dns; size_t dns_count; + sd_dns_resolver *dnr; + size_t n_dnr; char **domains; struct in6_addr *ntp; size_t ntp_count; diff --git a/src/libnm-systemd-core/src/libsystemd-network/dhcp6-network.c b/src/libnm-systemd-core/src/libsystemd-network/dhcp6-network.c index 7b17dbc1..03732692 100644 --- a/src/libnm-systemd-core/src/libsystemd-network/dhcp6-network.c +++ b/src/libnm-systemd-core/src/libsystemd-network/dhcp6-network.c @@ -19,9 +19,10 @@ #include "fd-util.h" #include "socket-util.h" -int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *local_address) { +int dhcp6_network_bind_udp_socket(int ifindex, const struct in6_addr *local_address) { union sockaddr_union src = { .in6.sin6_family = AF_INET6, + .in6.sin6_addr = *ASSERT_PTR(local_address), .in6.sin6_port = htobe16(DHCP6_PORT_CLIENT), .in6.sin6_scope_id = ifindex, }; @@ -29,9 +30,6 @@ int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *local_address) { int r; assert(ifindex > 0); - assert(local_address); - - src.in6.sin6_addr = *local_address; s = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, IPPROTO_UDP); if (s < 0) @@ -60,20 +58,14 @@ int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *local_address) { return TAKE_FD(s); } -int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address, - const void *packet, size_t len) { +int dhcp6_network_send_udp_socket(int s, const struct in6_addr *server_address, const void *packet, size_t len) { union sockaddr_union dest = { .in6.sin6_family = AF_INET6, + .in6.sin6_addr = *ASSERT_PTR(server_address), .in6.sin6_port = htobe16(DHCP6_PORT_SERVER), }; - int r; - - assert(server_address); - memcpy(&dest.in6.sin6_addr, server_address, sizeof(dest.in6.sin6_addr)); - - r = sendto(s, packet, len, 0, &dest.sa, sizeof(dest.in6)); - if (r < 0) + if (sendto(s, packet, len, 0, &dest.sa, sizeof(dest.in6)) < 0) return -errno; return 0; diff --git a/src/libnm-systemd-core/src/libsystemd-network/dhcp6-option.c b/src/libnm-systemd-core/src/libsystemd-network/dhcp6-option.c index 5fa9b265..4e30c9e5 100644 --- a/src/libnm-systemd-core/src/libsystemd-network/dhcp6-option.c +++ b/src/libnm-systemd-core/src/libsystemd-network/dhcp6-option.c @@ -208,6 +208,7 @@ bool dhcp6_option_can_request(uint16_t option) { case SD_DHCP6_OPTION_V6_DOTS_RI: case SD_DHCP6_OPTION_V6_DOTS_ADDRESS: case SD_DHCP6_OPTION_IPV6_ADDRESS_ANDSF: + case SD_DHCP6_OPTION_V6_DNR: return true; default: return false; @@ -822,74 +823,6 @@ int dhcp6_option_parse_addresses( return 0; } -static int parse_domain(const uint8_t **data, size_t *len, char **ret) { - _cleanup_free_ char *domain = NULL; - const uint8_t *optval; - size_t optlen, n = 0; - int r; - - assert(data); - assert(len); - assert(*data || *len == 0); - assert(ret); - - optval = *data; - optlen = *len; - - if (optlen <= 1) - return -ENODATA; - - for (;;) { - const char *label; - uint8_t c; - - if (optlen == 0) - break; - - c = *optval; - optval++; - optlen--; - - if (c == 0) - /* End label */ - break; - if (c > 63) - return -EBADMSG; - if (c > optlen) - return -EMSGSIZE; - - /* Literal label */ - label = (const char*) optval; - optval += c; - optlen -= c; - - if (!GREEDY_REALLOC(domain, n + (n != 0) + DNS_LABEL_ESCAPED_MAX)) - return -ENOMEM; - - if (n != 0) - domain[n++] = '.'; - - r = dns_label_escape(label, c, domain + n, DNS_LABEL_ESCAPED_MAX); - if (r < 0) - return r; - - n += r; - } - - if (n > 0) { - if (!GREEDY_REALLOC(domain, n + 1)) - return -ENOMEM; - - domain[n] = '\0'; - } - - *ret = TAKE_PTR(domain); - *data = optval; - *len = optlen; - - return n; -} - int dhcp6_option_parse_domainname(const uint8_t *optval, size_t optlen, char **ret) { _cleanup_free_ char *domain = NULL; int r; @@ -897,7 +830,7 @@ int dhcp6_option_parse_domainname(const uint8_t *optval, size_t optlen, char **r assert(optval || optlen == 0); assert(ret); - r = parse_domain(&optval, &optlen, &domain); + r = dns_name_from_wire_format(&optval, &optlen, &domain); if (r < 0) return r; if (r == 0) @@ -924,11 +857,11 @@ int dhcp6_option_parse_domainname_list(const uint8_t *optval, size_t optlen, cha while (optlen > 0) { _cleanup_free_ char *name = NULL; - r = parse_domain(&optval, &optlen, &name); + r = dns_name_from_wire_format(&optval, &optlen, &name); if (r < 0) return r; - if (r == 0) - continue; + if (dns_name_is_root(name)) /* root domain */ + return -EBADMSG; r = strv_consume(&names, TAKE_PTR(name)); if (r < 0) diff --git a/src/libnm-systemd-core/src/libsystemd-network/dhcp6-protocol.h b/src/libnm-systemd-core/src/libsystemd-network/dhcp6-protocol.h index c70f9320..39f5040f 100644 --- a/src/libnm-systemd-core/src/libsystemd-network/dhcp6-protocol.h +++ b/src/libnm-systemd-core/src/libsystemd-network/dhcp6-protocol.h @@ -28,9 +28,11 @@ typedef struct DHCP6Message DHCP6Message; #define DHCP6_MIN_OPTIONS_SIZE \ 1280 - sizeof(struct ip6_hdr) - sizeof(struct udphdr) -#define IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT \ - { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02 } } } +#define IN6_ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS \ + ((const struct in6_addr) { { { \ + 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, \ + } } } ) enum { DHCP6_PORT_SERVER = 547, @@ -150,9 +152,9 @@ typedef enum DHCP6FQDNFlag { DHCP6_FQDN_FLAG_N = 1 << 2, } DHCP6FQDNFlag; -const char *dhcp6_state_to_string(DHCP6State s) _const_; -const char *dhcp6_message_type_to_string(DHCP6MessageType s) _const_; +const char* dhcp6_state_to_string(DHCP6State s) _const_; +const char* dhcp6_message_type_to_string(DHCP6MessageType s) _const_; DHCP6MessageType dhcp6_message_type_from_string(const char *s) _pure_; -const char *dhcp6_message_status_to_string(DHCP6Status s) _const_; +const char* dhcp6_message_status_to_string(DHCP6Status s) _const_; DHCP6Status dhcp6_message_status_from_string(const char *s) _pure_; int dhcp6_message_status_to_errno(DHCP6Status s); diff --git a/src/libnm-systemd-core/src/libsystemd-network/network-common.c b/src/libnm-systemd-core/src/libsystemd-network/network-common.c index 8d62e6ff..f61b11f5 100644 --- a/src/libnm-systemd-core/src/libsystemd-network/network-common.c +++ b/src/libnm-systemd-core/src/libsystemd-network/network-common.c @@ -3,7 +3,7 @@ #include "nm-sd-adapt-core.h" #include "env-util.h" -#include "format-util.h" +#include "format-ifname.h" #include "network-common.h" #include "socket-util.h" #include "unaligned.h" diff --git a/src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-client.c b/src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-client.c index a6b55d07..5655c0d7 100644 --- a/src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-client.c @@ -749,8 +749,6 @@ static int client_append_mudurl(sd_dhcp6_client *client, uint8_t **buf, size_t * int dhcp6_client_send_message(sd_dhcp6_client *client) { _cleanup_free_ uint8_t *buf = NULL; - struct in6_addr all_servers = - IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT; struct sd_dhcp6_option *j; usec_t elapsed_usec, time_now; be16_t elapsed_time; @@ -845,7 +843,7 @@ int dhcp6_client_send_message(sd_dhcp6_client *client) { if (r < 0) return r; - r = dhcp6_network_send_udp_socket(client->fd, &all_servers, buf, offset); + r = dhcp6_network_send_udp_socket(client->fd, &IN6_ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS, buf, offset); if (r < 0) return r; @@ -1336,7 +1334,7 @@ static int client_receive_message( return 0; } if ((size_t) len < sizeof(DHCP6Message)) { - log_dhcp6_client(client, "Too small to be DHCP6 message: ignoring"); + log_dhcp6_client(client, "Too small to be DHCPv6 message: ignoring"); return 0; } @@ -1412,7 +1410,7 @@ int sd_dhcp6_client_stop(sd_dhcp6_client *client) { r = client_send_release(client); if (r < 0) log_dhcp6_client_errno(client, r, - "Failed to send DHCP6 release message, ignoring: %m"); + "Failed to send DHCPv6 release message, ignoring: %m"); client_stop(client, SD_DHCP6_CLIENT_EVENT_STOP); @@ -1423,7 +1421,8 @@ int sd_dhcp6_client_stop(sd_dhcp6_client *client) { } int sd_dhcp6_client_is_running(sd_dhcp6_client *client) { - assert_return(client, -EINVAL); + if (!client) + return false; return client->state != DHCP6_STATE_STOPPED; } diff --git a/src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-lease.c b/src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-lease.c index a42df243..9569af58 100644 --- a/src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/libnm-systemd-core/src/libsystemd-network/sd-dhcp6-lease.c @@ -10,7 +10,9 @@ #include "alloc-util.h" #include "dhcp6-internal.h" #include "dhcp6-lease-internal.h" +#include "dns-domain.h" #include "network-common.h" +#include "sort-util.h" #include "strv.h" #include "unaligned.h" @@ -426,7 +428,7 @@ int dhcp6_lease_add_domains(sd_dhcp6_lease *lease, const uint8_t *optval, size_t if (r < 0) return r; - return strv_extend_strv(&lease->domains, domains, true); + return strv_extend_strv_consume(&lease->domains, TAKE_PTR(domains), /* filter_duplicates = */ true); } int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***ret) { @@ -440,6 +442,105 @@ int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***ret) { return strv_length(lease->domains); } +#if 0 /* NM_IGNORED */ +static int dhcp6_lease_add_dnr(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) { + int r; + + assert(lease); + + _cleanup_(sd_dns_resolver_done) sd_dns_resolver res = {}; + + size_t offset = 0; + + /* priority */ + if (optlen - offset < sizeof(uint16_t)) + return -EBADMSG; + res.priority = unaligned_read_be16(optval + offset); + offset += sizeof(uint16_t); + + /* adn */ + if (optlen - offset < sizeof(uint16_t)) + return -EBADMSG; + size_t ilen = unaligned_read_be16(optval + offset); + offset += sizeof(uint16_t); + if (offset + ilen > optlen) + return -EBADMSG; + + r = dhcp6_option_parse_domainname(optval + offset, ilen, &res.auth_name); + if (r < 0) + return r; + r = dns_name_is_valid_ldh(res.auth_name); + if (r < 0) + return r; + if (!r) + return -EBADMSG; + offset += ilen; + + /* RFC9463 § 3.1.6: adn only mode */ + if (offset == optlen) + return 0; + + /* addrs */ + if (optlen - offset < sizeof(uint16_t)) + return -EBADMSG; + ilen = unaligned_read_be16(optval + offset); + offset += sizeof(uint16_t); + if (offset + ilen > optlen) + return -EBADMSG; + + _cleanup_free_ struct in6_addr *addrs = NULL; + size_t n_addrs = 0; + + r = dhcp6_option_parse_addresses(optval + offset, ilen, &addrs, &n_addrs); + if (r < 0) + return r; + if (n_addrs == 0) + return -EBADMSG; + offset += ilen; + + res.addrs = new(union in_addr_union, n_addrs); + if (!res.addrs) + return -ENOMEM; + + for (size_t i = 0; i < n_addrs; i++) { + union in_addr_union addr = {.in6 = addrs[i]}; + /* RFC9463 § 6.2 client MUST discard multicast and host loopback addresses */ + if (in_addr_is_multicast(AF_INET6, &addr) || + in_addr_is_localhost(AF_INET6, &addr)) + return -EBADMSG; + res.addrs[i] = addr; + } + res.n_addrs = n_addrs; + res.family = AF_INET6; + + /* svc params */ + r = dnr_parse_svc_params(optval + offset, optlen-offset, &res); + if (r < 0) + return r; + + /* Append this resolver */ + if (!GREEDY_REALLOC(lease->dnr, lease->n_dnr+1)) + return -ENOMEM; + + lease->dnr[lease->n_dnr++] = TAKE_STRUCT(res); + + typesafe_qsort(lease->dnr, lease->n_dnr, dns_resolver_prio_compare); + + return 1; +} + +int sd_dhcp6_lease_get_dnr(sd_dhcp6_lease *lease, sd_dns_resolver **ret) { + assert_return(lease, -EINVAL); + assert_return(ret, -EINVAL); + + if (!lease->dnr) + return -ENODATA; + + *ret = lease->dnr; + return lease->n_dnr; +} +#endif /* NM_IGNORED */ + int dhcp6_lease_add_ntp(sd_dhcp6_lease *lease, const uint8_t *optval, size_t optlen) { int r; @@ -765,8 +866,7 @@ static int dhcp6_lease_parse_message( continue; } - dhcp6_ia_free(lease->ia_na); - lease->ia_na = TAKE_PTR(ia); + free_and_replace_full(lease->ia_na, ia, dhcp6_ia_free); break; } case SD_DHCP6_OPTION_IA_PD: { @@ -790,8 +890,7 @@ static int dhcp6_lease_parse_message( continue; } - dhcp6_ia_free(lease->ia_pd); - lease->ia_pd = TAKE_PTR(ia); + free_and_replace_full(lease->ia_pd, ia, dhcp6_ia_free); break; } case SD_DHCP6_OPTION_RAPID_COMMIT: @@ -852,7 +951,16 @@ static int dhcp6_lease_parse_message( irt = unaligned_be32_sec_to_usec(optval, /* max_as_infinity = */ false); break; +#if 0 /* NM_IGNORED */ + case SD_DHCP6_OPTION_V6_DNR: + r = dhcp6_lease_add_dnr(lease, optval, optlen); + if (r < 0) + return log_dhcp6_client_errno(client, r, "Failed to parse DNR option, ignoring: %m"); + if (r == 0) + log_dhcp6_client(client, "Received ADN-only DNRv6 option, ignoring."); + break; +#endif /* NM_IGNORED */ case SD_DHCP6_OPTION_VENDOR_OPTS: r = dhcp6_lease_add_vendor_option(lease, optval, optlen); if (r < 0) @@ -906,6 +1014,9 @@ static sd_dhcp6_lease *dhcp6_lease_free(sd_dhcp6_lease *lease) { dhcp6_ia_free(lease->ia_na); dhcp6_ia_free(lease->ia_pd); free(lease->dns); +#if 0 /* NM_IGNORED */ + dns_resolver_done_many(lease->dnr, lease->n_dnr); +#endif /* NM_IGNORED */ free(lease->fqdn); free(lease->captive_portal); strv_free(lease->domains); diff --git a/src/libnm-systemd-core/src/libsystemd/sd-device/device-private.c b/src/libnm-systemd-core/src/libsystemd/sd-device/device-private.c index eef3d618..6b17e772 100644 --- a/src/libnm-systemd-core/src/libsystemd/sd-device/device-private.c +++ b/src/libnm-systemd-core/src/libsystemd/sd-device/device-private.c @@ -714,7 +714,7 @@ static int device_tag(sd_device *device, const char *tag, bool add) { assert(device); assert(tag); - r = device_get_device_id(device, &id); + r = sd_device_get_device_id(device, &id); if (r < 0) return r; @@ -801,7 +801,7 @@ static int device_get_db_path(sd_device *device, char **ret) { assert(device); assert(ret); - r = device_get_device_id(device, &id); + r = sd_device_get_device_id(device, &id); if (r < 0) return r; diff --git a/src/libnm-systemd-core/src/libsystemd/sd-device/device-private.h b/src/libnm-systemd-core/src/libsystemd/sd-device/device-private.h index e1f3b6e8..eab54203 100644 --- a/src/libnm-systemd-core/src/libsystemd/sd-device/device-private.h +++ b/src/libnm-systemd-core/src/libsystemd/sd-device/device-private.h @@ -20,10 +20,12 @@ int device_opendir(sd_device *device, const char *subdir, DIR **ret); int device_get_property_bool(sd_device *device, const char *key); int device_get_property_int(sd_device *device, const char *key, int *ret); int device_get_sysattr_int(sd_device *device, const char *sysattr, int *ret_value); -int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value); +int device_get_sysattr_unsigned_full(sd_device *device, const char *sysattr, unsigned base, unsigned *ret_value); +static inline int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value) { + return device_get_sysattr_unsigned_full(device, sysattr, 0, ret_value); +} int device_get_sysattr_u32(sd_device *device, const char *sysattr, uint32_t *ret_value); int device_get_sysattr_bool(sd_device *device, const char *sysattr); -int device_get_device_id(sd_device *device, const char **ret); int device_get_devlink_priority(sd_device *device, int *ret); int device_get_devnode_mode(sd_device *device, mode_t *ret); int device_get_devnode_uid(sd_device *device, uid_t *ret); @@ -73,5 +75,5 @@ int device_read_uevent_file(sd_device *device); int device_set_action(sd_device *device, sd_device_action_t a); sd_device_action_t device_action_from_string(const char *s) _pure_; -const char *device_action_to_string(sd_device_action_t a) _const_; +const char* device_action_to_string(sd_device_action_t a) _const_; void dump_device_action_table(void); diff --git a/src/libnm-systemd-core/src/libsystemd/sd-device/device-util.h b/src/libnm-systemd-core/src/libsystemd/sd-device/device-util.h index 534a2967..b17993d5 100644 --- a/src/libnm-systemd-core/src/libsystemd/sd-device/device-util.h +++ b/src/libnm-systemd-core/src/libsystemd/sd-device/device-util.h @@ -100,7 +100,7 @@ static inline int devname_from_stat_rdev(const struct stat *st, char **ret) { assert(st); return devname_from_devnum(st->st_mode, st->st_rdev, ret); } -int device_open_from_devnum(mode_t mode, dev_t devnum, int flags, char **ret); +int device_open_from_devnum(mode_t mode, dev_t devnum, int flags, char **ret_devname); char** device_make_log_fields(sd_device *device); diff --git a/src/libnm-systemd-core/src/libsystemd/sd-device/sd-device.c b/src/libnm-systemd-core/src/libsystemd/sd-device/sd-device.c index 0ca87146..480223d0 100644 --- a/src/libnm-systemd-core/src/libsystemd/sd-device/sd-device.c +++ b/src/libnm-systemd-core/src/libsystemd/sd-device/sd-device.c @@ -243,7 +243,7 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) { r = path_simplify_alloc(_syspath, &syspath); if (r < 0) - return r; + return log_oom_debug(); } assert_se(devpath = startswith(syspath, "/sys")); @@ -354,9 +354,11 @@ _public_ int sd_device_new_from_ifname(sd_device **ret, const char *ifname) { assert_return(ret, -EINVAL); assert_return(ifname, -EINVAL); - r = device_new_from_main_ifname(ret, ifname); - if (r >= 0) - return r; + if (ifname_valid(ifname)) { + r = device_new_from_main_ifname(ret, ifname); + if (r >= 0) + return r; + } r = rtnl_resolve_ifname_full(NULL, RESOLVE_IFNAME_ALTERNATIVE | RESOLVE_IFNAME_NUMERIC, ifname, &main_name, NULL); if (r < 0) @@ -393,25 +395,79 @@ _public_ int sd_device_new_from_ifindex(sd_device **ret, int ifindex) { return 0; } -static int device_strjoin_new( +static int device_new_from_path_join( + sd_device **device, + const char *subsystem, + const char *driver_subsystem, + const char *sysname, const char *a, const char *b, const char *c, - const char *d, - sd_device **ret) { + const char *d) { - const char *p; + _cleanup_(sd_device_unrefp) sd_device *new_device = NULL; + _cleanup_free_ char *p = NULL; int r; - p = strjoina(a, b, c, d); - if (access(p, F_OK) < 0) - return IN_SET(errno, ENOENT, ENAMETOOLONG) ? 0 : -errno; /* If this sysfs is too long then it doesn't exist either */ + assert(device); + assert(sysname); + + p = path_join(a, b, c, d); + if (!p) + return -ENOMEM; + + r = sd_device_new_from_syspath(&new_device, p); + if (r == -ENODEV) + return 0; + if (r < 0) + return r; + + /* Check if the found device really has the expected subsystem and sysname, for safety. */ + if (!device_in_subsystem(new_device, subsystem)) + return 0; + + const char *new_driver_subsystem = NULL; + (void) sd_device_get_driver_subsystem(new_device, &new_driver_subsystem); + + if (!streq_ptr(driver_subsystem, new_driver_subsystem)) + return 0; + + const char *new_sysname; + r = sd_device_get_sysname(new_device, &new_sysname); + if (r < 0) + return r; + + if (!streq(sysname, new_sysname)) + return 0; + + /* If this is the first device we found, then take it. */ + if (!*device) { + *device = TAKE_PTR(new_device); + return 1; + } + + /* Unfortunately, (subsystem, sysname) pair is not unique. For examples, + * - /sys/bus/gpio and /sys/class/gpio, both have gpiochip%N. However, these point to different devpaths. + * - /sys/bus/mdio_bus and /sys/class/mdio_bus, + * - /sys/bus/mei and /sys/class/mei, + * - /sys/bus/typec and /sys/class/typec, and so on. + * Hence, if we already know a device, then we need to check if it is equivalent to the newly found one. */ + + const char *devpath, *new_devpath; + r = sd_device_get_devpath(*device, &devpath); + if (r < 0) + return r; - r = sd_device_new_from_syspath(ret, p); + r = sd_device_get_devpath(new_device, &new_devpath); if (r < 0) return r; - return 1; + if (!streq(devpath, new_devpath)) + return log_debug_errno(SYNTHETIC_ERRNO(ETOOMANYREFS), + "sd-device: found multiple devices for subsystem=%s and sysname=%s, refusing: %s, %s", + subsystem, sysname, devpath, new_devpath); + + return 1; /* Fortunately, they are consistent. */ } _public_ int sd_device_new_from_subsystem_sysname( @@ -419,6 +475,7 @@ _public_ int sd_device_new_from_subsystem_sysname( const char *subsystem, const char *sysname) { + _cleanup_(sd_device_unrefp) sd_device *device = NULL; char *name; int r; @@ -437,19 +494,15 @@ _public_ int sd_device_new_from_subsystem_sysname( if (streq(subsystem, "subsystem")) { FOREACH_STRING(s, "/sys/bus/", "/sys/class/") { - r = device_strjoin_new(s, name, NULL, NULL, ret); + r = device_new_from_path_join(&device, subsystem, /* driver_subsystem = */ NULL, sysname, s, name, NULL, NULL); if (r < 0) return r; - if (r > 0) - return 0; } } else if (streq(subsystem, "module")) { - r = device_strjoin_new("/sys/module/", name, NULL, NULL, ret); + r = device_new_from_path_join(&device, subsystem, /* driver_subsystem = */ NULL, sysname, "/sys/module/", name, NULL, NULL); if (r < 0) return r; - if (r > 0) - return 0; } else if (streq(subsystem, "drivers")) { const char *sep; @@ -461,35 +514,33 @@ _public_ int sd_device_new_from_subsystem_sysname( sep++; if (streq(sep, "drivers")) /* If the sysname is "drivers", then it's the drivers directory itself that is meant. */ - r = device_strjoin_new("/sys/bus/", subsys, "/drivers", NULL, ret); + r = device_new_from_path_join(&device, subsystem, subsys, "drivers", "/sys/bus/", subsys, "/drivers", NULL); else - r = device_strjoin_new("/sys/bus/", subsys, "/drivers/", sep, ret); + r = device_new_from_path_join(&device, subsystem, subsys, sep, "/sys/bus/", subsys, "/drivers/", sep); if (r < 0) return r; - if (r > 0) - return 0; } } - r = device_strjoin_new("/sys/bus/", subsystem, "/devices/", name, ret); + r = device_new_from_path_join(&device, subsystem, /* driver_subsystem = */ NULL, sysname, "/sys/bus/", subsystem, "/devices/", name); if (r < 0) return r; - if (r > 0) - return 0; - r = device_strjoin_new("/sys/class/", subsystem, "/", name, ret); + r = device_new_from_path_join(&device, subsystem, /* driver_subsystem = */ NULL, sysname, "/sys/class/", subsystem, name, NULL); if (r < 0) return r; - if (r > 0) - return 0; - r = device_strjoin_new("/sys/firmware/", subsystem, "/", name, ret); + /* Note that devices under /sys/firmware/ (e.g. /sys/firmware/devicetree/base/) do not have + * subsystem. Hence, pass NULL for subsystem. See issue #35861. */ + r = device_new_from_path_join(&device, /* subsystem = */ NULL, /* driver_subsystem = */ NULL, sysname, "/sys/firmware/", subsystem, name, NULL); if (r < 0) return r; - if (r > 0) - return 0; - return -ENODEV; + if (!device) + return -ENODEV; + + *ret = TAKE_PTR(device); + return 0; } _public_ int sd_device_new_from_stat_rdev(sd_device **ret, const struct stat *st) { @@ -499,10 +550,8 @@ _public_ int sd_device_new_from_stat_rdev(sd_device **ret, const struct stat *st return device_new_from_mode_and_devnum(ret, st->st_mode, st->st_rdev); } -_public_ int sd_device_new_from_devname(sd_device **ret, const char *devname) { - struct stat st; - dev_t devnum; - mode_t mode; +static int device_new_from_devname(sd_device **ret, const char *devname, bool strict) { + int r; assert_return(ret, -EINVAL); assert_return(devname, -EINVAL); @@ -510,28 +559,41 @@ _public_ int sd_device_new_from_devname(sd_device **ret, const char *devname) { /* This function actually accepts both devlinks and devnames, i.e. both symlinks and device * nodes below /dev/. */ - /* Also ignore when the specified path is "/dev". */ - if (isempty(path_startswith(devname, "/dev"))) + if (strict && isempty(path_startswith(devname, "/dev/"))) return -EINVAL; + dev_t devnum; + mode_t mode; if (device_path_parse_major_minor(devname, &mode, &devnum) >= 0) /* Let's shortcut when "/dev/block/maj:min" or "/dev/char/maj:min" is specified. * In that case, we can directly convert the path to syspath, hence it is not necessary * that the specified path exists. So, this works fine without udevd being running. */ return device_new_from_mode_and_devnum(ret, mode, devnum); - if (stat(devname, &st) < 0) - return ERRNO_IS_DEVICE_ABSENT(errno) ? -ENODEV : -errno; + _cleanup_free_ char *resolved = NULL; + struct stat st; + r = chase_and_stat(devname, /* root = */ NULL, /* flags = */ 0, &resolved, &st); + if (ERRNO_IS_NEG_DEVICE_ABSENT(r)) + return -ENODEV; + if (r < 0) + return r; + + if (isempty(path_startswith(resolved, "/dev/"))) + return -EINVAL; return sd_device_new_from_stat_rdev(ret, &st); } +_public_ int sd_device_new_from_devname(sd_device **ret, const char *devname) { + return device_new_from_devname(ret, devname, /* strict = */ true); +} + _public_ int sd_device_new_from_path(sd_device **ret, const char *path) { assert_return(ret, -EINVAL); assert_return(path, -EINVAL); - if (path_startswith(path, "/dev")) - return sd_device_new_from_devname(ret, path); + if (device_new_from_devname(ret, path, /* strict = */ false) >= 0) + return 0; return device_new_from_syspath(ret, path, /* strict = */ false); } @@ -1211,6 +1273,20 @@ _public_ int sd_device_get_subsystem(sd_device *device, const char **ret) { } #if 0 /* NM_IGNORED */ +_public_ int sd_device_get_driver_subsystem(sd_device *device, const char **ret) { + assert_return(device, -EINVAL); + + if (!device_in_subsystem(device, "drivers")) + return -ENOENT; + + assert(device->driver_subsystem); + + if (ret) + *ret = device->driver_subsystem; + + return 0; +} + _public_ int sd_device_get_devtype(sd_device *device, const char **devtype) { int r; @@ -1226,7 +1302,7 @@ _public_ int sd_device_get_devtype(sd_device *device, const char **devtype) { if (devtype) *devtype = device->devtype; - return !!device->devtype; + return 0; } _public_ int sd_device_get_parent_with_subsystem_devtype(sd_device *device, const char *subsystem, const char *devtype, sd_device **ret) { @@ -1645,9 +1721,8 @@ static int handle_db_line(sd_device *device, char key, const char *value) { } } -int device_get_device_id(sd_device *device, const char **ret) { - assert(device); - assert(ret); +_public_ int sd_device_get_device_id(sd_device *device, const char **ret) { + assert_return(device, -EINVAL); if (!device->device_id) { _cleanup_free_ char *id = NULL; @@ -1697,7 +1772,8 @@ int device_get_device_id(sd_device *device, const char **ret) { device->device_id = TAKE_PTR(id); } - *ret = device->device_id; + if (ret) + *ret = device->device_id; return 0; } @@ -2428,7 +2504,7 @@ int device_get_sysattr_int(sd_device *device, const char *sysattr, int *ret_valu return v > 0; } -int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value) { +int device_get_sysattr_unsigned_full(sd_device *device, const char *sysattr, unsigned base, unsigned *ret_value) { const char *value; int r; @@ -2437,7 +2513,7 @@ int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned return r; unsigned v; - r = safe_atou(value, &v); + r = safe_atou_full(value, base, &v); if (r < 0) return log_device_debug_errno(device, r, "Failed to parse '%s' attribute: %m", sysattr); diff --git a/src/libnm-systemd-core/src/libsystemd/sd-event/event-source.h b/src/libnm-systemd-core/src/libsystemd/sd-event/event-source.h index f4e38d78..d05bcf05 100644 --- a/src/libnm-systemd-core/src/libsystemd/sd-event/event-source.h +++ b/src/libnm-systemd-core/src/libsystemd/sd-event/event-source.h @@ -189,6 +189,9 @@ struct inode_data { * iteration. */ int fd; + /* The path that the fd points to. The field is optional. */ + char *path; + /* The inotify "watch descriptor" */ int wd; diff --git a/src/libnm-systemd-core/src/libsystemd/sd-event/event-util.c b/src/libnm-systemd-core/src/libsystemd/sd-event/event-util.c index ef0c2d2a..ac986e48 100644 --- a/src/libnm-systemd-core/src/libsystemd/sd-event/event-util.c +++ b/src/libnm-systemd-core/src/libsystemd/sd-event/event-util.c @@ -171,4 +171,13 @@ int event_add_child_pidref( return sd_event_add_child(e, s, pid->pid, options, callback, userdata); } + +dual_timestamp* event_dual_timestamp_now(sd_event *e, dual_timestamp *ts) { + assert(e); + assert(ts); + + assert_se(sd_event_now(e, CLOCK_REALTIME, &ts->realtime) >= 0); + assert_se(sd_event_now(e, CLOCK_MONOTONIC, &ts->monotonic) >= 0); + return ts; +} #endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-core/src/libsystemd/sd-event/event-util.h b/src/libnm-systemd-core/src/libsystemd/sd-event/event-util.h index ad0f2e78..c0db014f 100644 --- a/src/libnm-systemd-core/src/libsystemd/sd-event/event-util.h +++ b/src/libnm-systemd-core/src/libsystemd/sd-event/event-util.h @@ -37,4 +37,6 @@ int event_add_time_change(sd_event *e, sd_event_source **ret, sd_event_io_handle #if 0 /* NM_IGNORED */ int event_add_child_pidref(sd_event *e, sd_event_source **s, const PidRef *pid, int options, sd_event_child_handler_t callback, void *userdata); + +dual_timestamp* event_dual_timestamp_now(sd_event *e, dual_timestamp *ts); #endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-core/src/libsystemd/sd-event/sd-event.c b/src/libnm-systemd-core/src/libsystemd/sd-event/sd-event.c index 6449b85c..b345b145 100644 --- a/src/libnm-systemd-core/src/libsystemd/sd-event/sd-event.c +++ b/src/libnm-systemd-core/src/libsystemd/sd-event/sd-event.c @@ -27,9 +27,11 @@ #include "missing_magic.h" #include "missing_syscall.h" #include "missing_threads.h" +#include "missing_wait.h" #include "origin-id.h" #include "path-util.h" #include "prioq.h" +#include "pidfd-util.h" #include "process-util.h" #include "psi-util.h" #include "set.h" @@ -184,7 +186,7 @@ static thread_local sd_event *default_event = NULL; static void source_disconnect(sd_event_source *s); static void event_gc_inode_data(sd_event *e, struct inode_data *d); -static sd_event *event_resolve(sd_event *e) { +static sd_event* event_resolve(sd_event *e) { return e == SD_EVENT_DEFAULT ? default_event : e; } @@ -340,7 +342,7 @@ static void free_clock_data(struct clock_data *d) { prioq_free(d->latest); } -static sd_event *event_free(sd_event *e) { +static sd_event* event_free(sd_event *e) { sd_event_source *s; assert(e); @@ -445,7 +447,7 @@ fail: } /* Define manually so we can add the origin check */ -_public_ sd_event *sd_event_ref(sd_event *e) { +_public_ sd_event* sd_event_ref(sd_event *e) { if (!e) return NULL; if (event_origin_changed(e)) @@ -473,8 +475,13 @@ _public_ sd_event* sd_event_unref(sd_event *e) { _unused_ _cleanup_(sd_event_unrefp) sd_event *_ref = sd_event_ref(e); _public_ sd_event_source* sd_event_source_disable_unref(sd_event_source *s) { - if (s) - (void) sd_event_source_set_enabled(s, SD_EVENT_OFF); + int r; + + r = sd_event_source_set_enabled(s, SD_EVENT_OFF); + if (r < 0) + log_debug_errno(r, "Failed to disable event source %p (%s): %m", + s, strna(s->description)); + return sd_event_source_unref(s); } @@ -1072,6 +1079,8 @@ static void source_disconnect(sd_event_source *s) { } static sd_event_source* source_free(sd_event_source *s) { + int r; + assert(s); source_disconnect(s); @@ -1085,31 +1094,23 @@ static sd_event_source* source_free(sd_event_source *s) { if (s->child.process_owned) { if (!s->child.exited) { - bool sent = false; - - if (s->child.pidfd >= 0) { - if (pidfd_send_signal(s->child.pidfd, SIGKILL, NULL, 0) < 0) { - if (errno == ESRCH) /* Already dead */ - sent = true; - else if (!ERRNO_IS_NOT_SUPPORTED(errno)) - log_debug_errno(errno, "Failed to kill process " PID_FMT " via pidfd_send_signal(), re-trying via kill(): %m", - s->child.pid); - } else - sent = true; - } - - if (!sent) - if (kill(s->child.pid, SIGKILL) < 0) - if (errno != ESRCH) /* Already dead */ - log_debug_errno(errno, "Failed to kill process " PID_FMT " via kill(), ignoring: %m", - s->child.pid); + if (s->child.pidfd >= 0) + r = RET_NERRNO(pidfd_send_signal(s->child.pidfd, SIGKILL, NULL, 0)); + else + r = RET_NERRNO(kill(s->child.pid, SIGKILL)); + if (r < 0 && r != -ESRCH) + log_debug_errno(r, "Failed to kill process " PID_FMT ", ignoring: %m", + s->child.pid); } if (!s->child.waited) { siginfo_t si = {}; /* Reap the child if we can */ - (void) waitid(P_PID, s->child.pid, &si, WEXITED); + if (s->child.pidfd >= 0) + (void) waitid(P_PIDFD, s->child.pidfd, &si, WEXITED); + else + (void) waitid(P_PID, s->child.pid, &si, WEXITED); } } @@ -1179,7 +1180,7 @@ static int source_set_pending(sd_event_source *s, bool b) { return 1; } -static sd_event_source *source_new(sd_event *e, bool floating, EventSourceType type) { +static sd_event_source* source_new(sd_event *e, bool floating, EventSourceType type) { /* Let's allocate exactly what we need. Note that the difference of the smallest event source * structure to the largest is 144 bytes on x86-64 at the time of writing, i.e. more than two cache @@ -1577,11 +1578,6 @@ static int child_exit_callback(sd_event_source *s, const siginfo_t *si, void *us return sd_event_exit(sd_event_source_get_event(s), PTR_TO_INT(userdata)); } -static bool shall_use_pidfd(void) { - /* Mostly relevant for debugging, i.e. this is used in test-event.c to test the event loop once with and once without pidfd */ - return secure_getenv_bool("SYSTEMD_PIDFD") != 0; -} - _public_ int sd_event_add_child( sd_event *e, sd_event_source **ret, @@ -1629,34 +1625,29 @@ _public_ int sd_event_add_child( if (!s) return -ENOMEM; + /* We always take a pidfd here if we can, even if we wait for anything else than WEXITED, so that we + * pin the PID, and make regular waitid() handling race-free. */ + + s->child.pidfd = pidfd_open(pid, 0); + if (s->child.pidfd < 0) + return -errno; + + s->child.pidfd_owned = true; /* If we allocate the pidfd we own it by default */ + s->wakeup = WAKEUP_EVENT_SOURCE; s->child.options = options; s->child.callback = callback; s->userdata = userdata; s->enabled = SD_EVENT_ONESHOT; - /* We always take a pidfd here if we can, even if we wait for anything else than WEXITED, so that we - * pin the PID, and make regular waitid() handling race-free. */ - - if (shall_use_pidfd()) { - s->child.pidfd = pidfd_open(pid, 0); - if (s->child.pidfd < 0) { - /* Propagate errors unless the syscall is not supported or blocked */ - if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno)) - return -errno; - } else - s->child.pidfd_owned = true; /* If we allocate the pidfd we own it by default */ - } else - s->child.pidfd = -EBADF; - if (EVENT_SOURCE_WATCH_PIDFD(s)) { - /* We have a pidfd and we only want to watch for exit */ + /* We only want to watch for exit */ r = source_child_pidfd_register(s, s->enabled); if (r < 0) return r; } else { - /* We have no pidfd or we shall wait for some other event than WEXITED */ + /* We shall wait for some other event than WEXITED */ r = event_make_signal_data(e, SIGCHLD, NULL); if (r < 0) return r; @@ -1686,7 +1677,6 @@ _public_ int sd_event_add_child_pidfd( sd_event_child_handler_t callback, void *userdata) { - _cleanup_(source_freep) sd_event_source *s = NULL; pid_t pid; int r; @@ -1727,17 +1717,12 @@ _public_ int sd_event_add_child_pidfd( s->wakeup = WAKEUP_EVENT_SOURCE; s->child.pidfd = pidfd; - s->child.pid = pid; s->child.options = options; s->child.callback = callback; s->child.pidfd_owned = false; /* If we got the pidfd passed in we don't own it by default (similar to the IO fd case) */ s->userdata = userdata; s->enabled = SD_EVENT_ONESHOT; - r = hashmap_put(e->child_sources, PID_TO_PTR(pid), s); - if (r < 0) - return r; - if (EVENT_SOURCE_WATCH_PIDFD(s)) { /* We only want to watch for WEXITED */ r = source_child_pidfd_register(s, s->enabled); @@ -1752,6 +1737,11 @@ _public_ int sd_event_add_child_pidfd( e->need_process_child = true; } + r = hashmap_put(e->child_sources, PID_TO_PTR(pid), s); + if (r < 0) + return r; + + s->child.pid = pid; e->n_online_child_sources++; if (ret) @@ -2280,6 +2270,7 @@ static void event_free_inode_data( assert_se(hashmap_remove(d->inotify_data->inodes, d) == d); } + free(d->path); free(d); } @@ -2423,7 +2414,7 @@ static int inode_data_realize_watch(sd_event *e, struct inode_data *d) { wd = inotify_add_watch_fd(d->inotify_data->fd, d->fd, combined_mask); if (wd < 0) - return -errno; + return wd; if (d->wd < 0) { r = hashmap_put(d->inotify_data->wd, INT_TO_PTR(wd), d); @@ -2445,6 +2436,7 @@ static int inode_data_realize_watch(sd_event *e, struct inode_data *d) { return 1; } +#if 0 /* NM_IGNORED */ static int inotify_exit_callback(sd_event_source *s, const struct inotify_event *event, void *userdata) { assert(s); @@ -2520,6 +2512,15 @@ static int event_add_inotify_fd_internal( } LIST_PREPEND(to_close, e->inode_data_to_close_list, inode_data); + + _cleanup_free_ char *path = NULL; + r = fd_get_path(inode_data->fd, &path); + if (r < 0 && r != -ENOSYS) { /* The path is optional, hence ignore -ENOSYS. */ + event_gc_inode_data(e, inode_data); + return r; + } + + free_and_replace(inode_data->path, path); } /* Link our event source to the inode data object */ @@ -2579,6 +2580,7 @@ _public_ int sd_event_add_inotify( return r; } +#endif /* NM_IGNORED */ static sd_event_source* event_source_free(sd_event_source *s) { if (!s) @@ -2609,18 +2611,18 @@ _public_ int sd_event_source_set_description(sd_event_source *s, const char *des return free_and_strdup(&s->description, description); } -_public_ int sd_event_source_get_description(sd_event_source *s, const char **description) { +_public_ int sd_event_source_get_description(sd_event_source *s, const char **ret) { assert_return(s, -EINVAL); - assert_return(description, -EINVAL); + assert_return(ret, -EINVAL); if (!s->description) return -ENXIO; - *description = s->description; + *ret = s->description; return 0; } -_public_ sd_event *sd_event_source_get_event(sd_event_source *s) { +_public_ sd_event* sd_event_source_get_event(sd_event_source *s) { assert_return(s, NULL); assert_return(!event_origin_changed(s->event), NULL); @@ -2645,7 +2647,7 @@ _public_ int sd_event_source_get_io_fd(sd_event_source *s) { } _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) { - int r; + int saved_fd, r; assert_return(s, -EINVAL); assert_return(fd >= 0, -EBADF); @@ -2655,16 +2657,12 @@ _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) { if (s->io.fd == fd) return 0; - if (event_source_is_offline(s)) { - s->io.fd = fd; - s->io.registered = false; - } else { - int saved_fd; + saved_fd = s->io.fd; + s->io.fd = fd; - saved_fd = s->io.fd; - assert(s->io.registered); + assert(event_source_is_offline(s) == !s->io.registered); - s->io.fd = fd; + if (s->io.registered) { s->io.registered = false; r = source_io_register(s, s->enabled, s->io.events); @@ -2677,6 +2675,9 @@ _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) { (void) epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, saved_fd, NULL); } + if (s->io.owned) + safe_close(saved_fd); + return 0; } @@ -2697,13 +2698,13 @@ _public_ int sd_event_source_set_io_fd_own(sd_event_source *s, int own) { return 0; } -_public_ int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events) { +_public_ int sd_event_source_get_io_events(sd_event_source *s, uint32_t *ret) { assert_return(s, -EINVAL); - assert_return(events, -EINVAL); + assert_return(ret, -EINVAL); assert_return(s->type == SOURCE_IO, -EDOM); assert_return(!event_origin_changed(s->event), -ECHILD); - *events = s->io.events; + *ret = s->io.events; return 0; } @@ -2735,14 +2736,14 @@ _public_ int sd_event_source_set_io_events(sd_event_source *s, uint32_t events) return 0; } -_public_ int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents) { +_public_ int sd_event_source_get_io_revents(sd_event_source *s, uint32_t *ret) { assert_return(s, -EINVAL); - assert_return(revents, -EINVAL); + assert_return(ret, -EINVAL); assert_return(s->type == SOURCE_IO, -EDOM); assert_return(s->pending, -ENODATA); assert_return(!event_origin_changed(s->event), -ECHILD); - *revents = s->io.revents; + *ret = s->io.revents; return 0; } @@ -2754,11 +2755,12 @@ _public_ int sd_event_source_get_signal(sd_event_source *s) { return s->signal.sig; } -_public_ int sd_event_source_get_priority(sd_event_source *s, int64_t *priority) { +_public_ int sd_event_source_get_priority(sd_event_source *s, int64_t *ret) { assert_return(s, -EINVAL); + assert_return(ret, -EINVAL); assert_return(!event_origin_changed(s->event), -ECHILD); - *priority = s->priority; + *ret = s->priority; return 0; } @@ -2806,6 +2808,13 @@ _public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority) } LIST_PREPEND(to_close, s->event->inode_data_to_close_list, new_inode_data); + + _cleanup_free_ char *path = NULL; + r = fd_get_path(new_inode_data->fd, &path); + if (r < 0 && r != -ENOSYS) + goto fail; + + free_and_replace(new_inode_data->path, path); } /* Move the event source to the new inode data structure */ @@ -3092,13 +3101,13 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) { return 0; } -_public_ int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) { +_public_ int sd_event_source_get_time(sd_event_source *s, uint64_t *ret) { assert_return(s, -EINVAL); - assert_return(usec, -EINVAL); + assert_return(ret, -EINVAL); assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM); assert_return(!event_origin_changed(s->event), -ECHILD); - *usec = s->time.next; + *ret = s->time.next; return 0; } @@ -3142,13 +3151,13 @@ _public_ int sd_event_source_set_time_relative(sd_event_source *s, uint64_t usec return sd_event_source_set_time(s, usec); } -_public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec) { +_public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *ret) { assert_return(s, -EINVAL); - assert_return(usec, -EINVAL); + assert_return(ret, -EINVAL); assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM); assert_return(!event_origin_changed(s->event), -ECHILD); - *usec = s->time.accuracy; + *ret = s->time.accuracy; return 0; } @@ -3174,23 +3183,23 @@ _public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec return 0; } -_public_ int sd_event_source_get_time_clock(sd_event_source *s, clockid_t *clock) { +_public_ int sd_event_source_get_time_clock(sd_event_source *s, clockid_t *ret) { assert_return(s, -EINVAL); - assert_return(clock, -EINVAL); + assert_return(ret, -EINVAL); assert_return(EVENT_SOURCE_IS_TIME(s->type), -EDOM); assert_return(!event_origin_changed(s->event), -ECHILD); - *clock = event_source_type_to_clock(s->type); + *ret = event_source_type_to_clock(s->type); return 0; } -_public_ int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid) { +_public_ int sd_event_source_get_child_pid(sd_event_source *s, pid_t *ret) { assert_return(s, -EINVAL); - assert_return(pid, -EINVAL); + assert_return(ret, -EINVAL); assert_return(s->type == SOURCE_CHILD, -EDOM); assert_return(!event_origin_changed(s->event), -ECHILD); - *pid = s->child.pid; + *ret = s->child.pid; return 0; } @@ -3225,12 +3234,10 @@ _public_ int sd_event_source_send_child_signal(sd_event_source *s, int sig, cons if (si) copy = *si; - if (pidfd_send_signal(s->child.pidfd, sig, si ? © : NULL, 0) < 0) { - /* Let's propagate the error only if the system call is not implemented or prohibited */ - if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno)) - return -errno; - } else - return 0; + if (pidfd_send_signal(s->child.pidfd, sig, si ? © : NULL, 0) < 0) + return -errno; + + return 0; } /* Flags are only supported for pidfd_send_signal(), not for rt_sigqueueinfo(), hence let's refuse @@ -3290,13 +3297,29 @@ _public_ int sd_event_source_set_child_process_own(sd_event_source *s, int own) return 0; } -_public_ int sd_event_source_get_inotify_mask(sd_event_source *s, uint32_t *mask) { +_public_ int sd_event_source_get_inotify_mask(sd_event_source *s, uint32_t *ret) { + assert_return(s, -EINVAL); + assert_return(ret, -EINVAL); + assert_return(s->type == SOURCE_INOTIFY, -EDOM); + assert_return(!event_origin_changed(s->event), -ECHILD); + + *ret = s->inotify.mask; + return 0; +} + +_public_ int sd_event_source_get_inotify_path(sd_event_source *s, const char **ret) { assert_return(s, -EINVAL); - assert_return(mask, -EINVAL); + assert_return(ret, -EINVAL); assert_return(s->type == SOURCE_INOTIFY, -EDOM); assert_return(!event_origin_changed(s->event), -ECHILD); - *mask = s->inotify.mask; + if (!s->inotify.inode_data) + return -ESTALE; /* already disconnected. */ + + if (!s->inotify.inode_data->path) + return -ENOSYS; /* /proc was not mounted? */ + + *ret = s->inotify.inode_data->path; return 0; } @@ -3839,7 +3862,8 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events, i if (_unlikely_(n != sizeof(si))) return -EIO; - assert(SIGNAL_VALID(si.ssi_signo)); + if (_unlikely_(!SIGNAL_VALID(si.ssi_signo))) + return -EIO; if (e->signal_sources) s = e->signal_sources[si.ssi_signo]; @@ -4540,7 +4564,7 @@ static int epoll_wait_usec( /* epoll_pwait2() was added to Linux 5.11 (2021-02-14) and to glibc in 2.35 (2022-02-03). In contrast * to other syscalls we don't bother with our own fallback syscall wrappers on old libcs, since this * is not that obvious to implement given the libc and kernel definitions differ in the last - * argument. Moreover, the only reason to use it is the more accurate time-outs (which is not a + * argument. Moreover, the only reason to use it is the more accurate timeouts (which is not a * biggie), let's hence rely on glibc's definitions, and fallback to epoll_pwait() when that's * missing. */ @@ -4825,13 +4849,13 @@ _public_ int sd_event_dispatch(sd_event *e) { static void event_log_delays(sd_event *e) { char b[ELEMENTSOF(e->delays) * DECIMAL_STR_MAX(unsigned) + 1], *p; - size_t l, i; + size_t l; p = b; l = sizeof(b); - for (i = 0; i < ELEMENTSOF(e->delays); i++) { - l = strpcpyf(&p, l, "%u ", e->delays[i]); - e->delays[i] = 0; + FOREACH_ELEMENT(delay, e->delays) { + l = strpcpyf(&p, l, "%u ", *delay); + *delay = 0; } log_debug("Event loop iterations: %s", b); } @@ -4892,7 +4916,6 @@ _public_ int sd_event_loop(sd_event *e) { assert_return(!event_origin_changed(e), -ECHILD); assert_return(e->state == SD_EVENT_INITIAL, -EBUSY); - PROTECT_EVENT(e); while (e->state != SD_EVENT_FINISHED) { @@ -4920,7 +4943,7 @@ _public_ int sd_event_get_state(sd_event *e) { return e->state; } -_public_ int sd_event_get_exit_code(sd_event *e, int *code) { +_public_ int sd_event_get_exit_code(sd_event *e, int *ret) { assert_return(e, -EINVAL); assert_return(e = event_resolve(e), -ENOPKG); assert_return(!event_origin_changed(e), -ECHILD); @@ -4928,8 +4951,8 @@ _public_ int sd_event_get_exit_code(sd_event *e, int *code) { if (!e->exit_requested) return -ENODATA; - if (code) - *code = e->exit_code; + if (ret) + *ret = e->exit_code; return 0; } @@ -4945,10 +4968,10 @@ _public_ int sd_event_exit(sd_event *e, int code) { return 0; } -_public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) { +_public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *ret) { assert_return(e, -EINVAL); assert_return(e = event_resolve(e), -ENOPKG); - assert_return(usec, -EINVAL); + assert_return(ret, -EINVAL); assert_return(!event_origin_changed(e), -ECHILD); if (!TRIPLE_TIMESTAMP_HAS_CLOCK(clock)) @@ -4956,11 +4979,11 @@ _public_ int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec) { if (!triple_timestamp_is_set(&e->timestamp)) { /* Implicitly fall back to now() if we never ran before and thus have no cached time. */ - *usec = now(clock); + *ret = now(clock); return 1; } - *usec = triple_timestamp_by_clock(&e->timestamp, clock); + *ret = triple_timestamp_by_clock(&e->timestamp, clock); return 0; } @@ -4989,18 +5012,17 @@ _public_ int sd_event_default(sd_event **ret) { } #if 0 /* NM_IGNORED */ -_public_ int sd_event_get_tid(sd_event *e, pid_t *tid) { +_public_ int sd_event_get_tid(sd_event *e, pid_t *ret) { assert_return(e, -EINVAL); assert_return(e = event_resolve(e), -ENOPKG); - assert_return(tid, -EINVAL); + assert_return(ret, -EINVAL); assert_return(!event_origin_changed(e), -ECHILD); - if (e->tid != 0) { - *tid = e->tid; - return 0; - } + if (e->tid == 0) + return -ENXIO; - return -ENXIO; + *ret = e->tid; + return 0; } _public_ int sd_event_set_watchdog(sd_event *e, int b) { @@ -5230,6 +5252,9 @@ _public_ int sd_event_set_signal_exit(sd_event *e, int b) { int r; assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); + assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); + assert_return(!event_origin_changed(e), -ECHILD); if (b) { /* We want to maintain pointers to these event sources, so that we can destroy them when told @@ -5241,7 +5266,7 @@ _public_ int sd_event_set_signal_exit(sd_event *e, int b) { if (r < 0) return r; - assert(sd_event_source_set_floating(e->sigint_event_source, true) >= 0); + assert_se(sd_event_source_set_floating(e->sigint_event_source, true) >= 0); change = true; } @@ -5249,26 +5274,26 @@ _public_ int sd_event_set_signal_exit(sd_event *e, int b) { r = sd_event_add_signal(e, &e->sigterm_event_source, SIGTERM | SD_EVENT_SIGNAL_PROCMASK, NULL, NULL); if (r < 0) { if (change) { - assert(sd_event_source_set_floating(e->sigint_event_source, false) >= 0); + assert_se(sd_event_source_set_floating(e->sigint_event_source, false) >= 0); e->sigint_event_source = sd_event_source_unref(e->sigint_event_source); } return r; } - assert(sd_event_source_set_floating(e->sigterm_event_source, true) >= 0); + assert_se(sd_event_source_set_floating(e->sigterm_event_source, true) >= 0); change = true; } } else { if (e->sigint_event_source) { - assert(sd_event_source_set_floating(e->sigint_event_source, false) >= 0); + assert_se(sd_event_source_set_floating(e->sigint_event_source, false) >= 0); e->sigint_event_source = sd_event_source_unref(e->sigint_event_source); change = true; } if (e->sigterm_event_source) { - assert(sd_event_source_set_floating(e->sigterm_event_source, false) >= 0); + assert_se(sd_event_source_set_floating(e->sigterm_event_source, false) >= 0); e->sigterm_event_source = sd_event_source_unref(e->sigterm_event_source); change = true; } diff --git a/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.c b/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.c index 58173055..6d515a94 100644 --- a/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.c +++ b/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.c @@ -11,6 +11,8 @@ #include "hexdecoct.h" #include "id128-util.h" #include "io-util.h" +#include "namespace-util.h" +#include "process-util.h" #include "sha256.h" #include "stdio-util.h" #include "string-util.h" @@ -273,4 +275,65 @@ sd_id128_t id128_digest(const void *data, size_t size) { return id128_make_v4_uuid(id); } + +int id128_get_boot_for_machine(const char *machine, sd_id128_t *ret) { + _cleanup_close_ int pidnsfd = -EBADF, mntnsfd = -EBADF, rootfd = -EBADF; + _cleanup_close_pair_ int pair[2] = EBADF_PAIR; + pid_t pid, child; + sd_id128_t id; + ssize_t k; + int r; + + assert(ret); + + if (isempty(machine)) + return sd_id128_get_boot(ret); + + r = container_get_leader(machine, &pid); + if (r < 0) + return r; + + r = namespace_open(pid, &pidnsfd, &mntnsfd, /* ret_netns_fd = */ NULL, /* ret_userns_fd = */ NULL, &rootfd); + if (r < 0) + return r; + + if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0) + return -errno; + + r = namespace_fork("(sd-bootidns)", "(sd-bootid)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL, + pidnsfd, mntnsfd, -1, -1, rootfd, &child); + if (r < 0) + return r; + if (r == 0) { + pair[0] = safe_close(pair[0]); + + r = id128_get_boot(&id); + if (r < 0) + _exit(EXIT_FAILURE); + + k = send(pair[1], &id, sizeof(id), MSG_NOSIGNAL); + if (k != sizeof(id)) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + pair[1] = safe_close(pair[1]); + + r = wait_for_terminate_and_check("(sd-bootidns)", child, 0); + if (r < 0) + return r; + if (r != EXIT_SUCCESS) + return -EIO; + + k = recv(pair[0], &id, sizeof(id), 0); + if (k != sizeof(id)) + return -EIO; + + if (sd_id128_is_null(id)) + return -EIO; + + *ret = id; + return 0; +} #endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.h b/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.h index 53ba50a8..458d4307 100644 --- a/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.h +++ b/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.h @@ -49,6 +49,9 @@ int id128_get_product(sd_id128_t *ret); sd_id128_t id128_digest(const void *data, size_t size); +int id128_get_boot(sd_id128_t *ret); +int id128_get_boot_for_machine(const char *machine, sd_id128_t *ret); + /* A helper to check for the three relevant cases of "machine ID not initialized" */ #define ERRNO_IS_NEG_MACHINE_ID_UNSET(r) \ IN_SET(r, \ diff --git a/src/libnm-systemd-core/src/libsystemd/sd-id128/sd-id128.c b/src/libnm-systemd-core/src/libsystemd/sd-id128/sd-id128.c index ff0db776..9f6ef719 100644 --- a/src/libnm-systemd-core/src/libsystemd/sd-id128/sd-id128.c +++ b/src/libnm-systemd-core/src/libsystemd/sd-id128/sd-id128.c @@ -15,6 +15,7 @@ #include "hmac.h" #include "id128-util.h" #include "io-util.h" +#include "keyring-util.h" #include "macro.h" #include "missing_syscall.h" #include "missing_threads.h" @@ -176,14 +177,24 @@ int id128_get_machine(const char *root, sd_id128_t *ret) { } #endif /* NM_IGNORED */ +int id128_get_boot(sd_id128_t *ret) { + int r; + + assert(ret); + + r = id128_read("/proc/sys/kernel/random/boot_id", ID128_FORMAT_UUID | ID128_REFUSE_NULL, ret); + if (r == -ENOENT && proc_mounted() == 0) + return -ENOSYS; + + return r; +} + _public_ int sd_id128_get_boot(sd_id128_t *ret) { static thread_local sd_id128_t saved_boot_id = {}; int r; if (sd_id128_is_null(saved_boot_id)) { - r = id128_read("/proc/sys/kernel/random/boot_id", ID128_FORMAT_UUID | ID128_REFUSE_NULL, &saved_boot_id); - if (r == -ENOENT && proc_mounted() == 0) - return -ENOSYS; + r = id128_get_boot(&saved_boot_id); if (r < 0) return r; } @@ -199,7 +210,6 @@ static int get_invocation_from_keyring(sd_id128_t *ret) { char *d, *p, *g, *u, *e; unsigned long perms; key_serial_t key; - size_t sz = 256; uid_t uid; gid_t gid; int r, c; @@ -218,24 +228,9 @@ static int get_invocation_from_keyring(sd_id128_t *ret) { return -errno; } - for (;;) { - description = new(char, sz); - if (!description) - return -ENOMEM; - - c = keyctl(KEYCTL_DESCRIBE, key, (unsigned long) description, sz, 0); - if (c < 0) - return -errno; - - if ((size_t) c <= sz) - break; - - sz = c; - free(description); - } - - /* The kernel returns a final NUL in the string, verify that. */ - assert(description[c-1] == 0); + r = keyring_describe(key, &description); + if (r < 0) + return r; /* Chop off the final description string */ d = strrchr(description, ';'); @@ -387,4 +382,17 @@ _public_ int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret) return sd_id128_get_app_specific(id, app_id, ret); } + +_public_ int sd_id128_get_invocation_app_specific(sd_id128_t app_id, sd_id128_t *ret) { + sd_id128_t id; + int r; + + assert_return(ret, -EINVAL); + + r = sd_id128_get_invocation(&id); + if (r < 0) + return r; + + return sd_id128_get_app_specific(id, app_id, ret); +} #endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-core/src/systemd/_sd-common.h b/src/libnm-systemd-core/src/systemd/_sd-common.h index d4381d90..5792dd81 100644 --- a/src/libnm-systemd-core/src/systemd/_sd-common.h +++ b/src/libnm-systemd-core/src/systemd/_sd-common.h @@ -45,6 +45,10 @@ typedef void (*_sd_destroy_t)(void *userdata); # define _sd_pure_ __attribute__((__pure__)) #endif +#ifndef _sd_const_ +# define _sd_const_ __attribute__((__const__)) +#endif + /* Note that strictly speaking __deprecated__ has been available before GCC 6. However, starting with GCC 6 * it also works on enum values, which we are interested in. Since this is a developer-facing feature anyway * (as opposed to build engineer-facing), let's hence conditionalize this to gcc 6, given that the developers @@ -105,4 +109,11 @@ typedef void (*_sd_destroy_t)(void *userdata); _SD_##id##_INT64_MIN = INT64_MIN, \ _SD_##id##_INT64_MAX = INT64_MAX +/* In GCC 14 (C23) we can force enums to have the right types, and not solely rely on language extensions anymore */ +#if ((__GNUC__ >= 14) || (__STDC_VERSION__ >= 202311L)) && !defined(__cplusplus) +# define _SD_ENUM_TYPE_S64(id) id : int64_t +#else +# define _SD_ENUM_TYPE_S64(id) id +#endif + #endif diff --git a/src/libnm-systemd-core/src/systemd/sd-device.h b/src/libnm-systemd-core/src/systemd/sd-device.h index b67ec0f3..f627ae6d 100644 --- a/src/libnm-systemd-core/src/systemd/sd-device.h +++ b/src/libnm-systemd-core/src/systemd/sd-device.h @@ -34,7 +34,7 @@ typedef struct sd_device sd_device; typedef struct sd_device_enumerator sd_device_enumerator; typedef struct sd_device_monitor sd_device_monitor; -__extension__ typedef enum sd_device_action_t { +__extension__ typedef enum _SD_ENUM_TYPE_S64(sd_device_action_t) { SD_DEVICE_ADD, SD_DEVICE_REMOVE, SD_DEVICE_CHANGE, @@ -74,6 +74,7 @@ int sd_device_get_parent_with_subsystem_devtype(sd_device *child, const char *su int sd_device_get_syspath(sd_device *device, const char **ret); int sd_device_get_subsystem(sd_device *device, const char **ret); +int sd_device_get_driver_subsystem(sd_device *device, const char **ret); int sd_device_get_devtype(sd_device *device, const char **ret); int sd_device_get_devnum(sd_device *device, dev_t *devnum); int sd_device_get_ifindex(sd_device *device, int *ifindex); @@ -85,21 +86,22 @@ int sd_device_get_sysnum(sd_device *device, const char **ret); int sd_device_get_action(sd_device *device, sd_device_action_t *ret); int sd_device_get_seqnum(sd_device *device, uint64_t *ret); int sd_device_get_diskseq(sd_device *device, uint64_t *ret); +int sd_device_get_device_id(sd_device *device, const char **ret); int sd_device_get_is_initialized(sd_device *device); int sd_device_get_usec_initialized(sd_device *device, uint64_t *ret); int sd_device_get_usec_since_initialized(sd_device *device, uint64_t *ret); -const char *sd_device_get_tag_first(sd_device *device); -const char *sd_device_get_tag_next(sd_device *device); -const char *sd_device_get_current_tag_first(sd_device *device); -const char *sd_device_get_current_tag_next(sd_device *device); -const char *sd_device_get_devlink_first(sd_device *device); -const char *sd_device_get_devlink_next(sd_device *device); -const char *sd_device_get_property_first(sd_device *device, const char **value); -const char *sd_device_get_property_next(sd_device *device, const char **value); -const char *sd_device_get_sysattr_first(sd_device *device); -const char *sd_device_get_sysattr_next(sd_device *device); +const char* sd_device_get_tag_first(sd_device *device); +const char* sd_device_get_tag_next(sd_device *device); +const char* sd_device_get_current_tag_first(sd_device *device); +const char* sd_device_get_current_tag_next(sd_device *device); +const char* sd_device_get_devlink_first(sd_device *device); +const char* sd_device_get_devlink_next(sd_device *device); +const char* sd_device_get_property_first(sd_device *device, const char **value); +const char* sd_device_get_property_next(sd_device *device, const char **value); +const char* sd_device_get_sysattr_first(sd_device *device); +const char* sd_device_get_sysattr_next(sd_device *device); sd_device *sd_device_get_child_first(sd_device *device, const char **ret_suffix); sd_device *sd_device_get_child_next(sd_device *device, const char **ret_suffix); @@ -135,6 +137,7 @@ int sd_device_enumerator_add_nomatch_sysname(sd_device_enumerator *enumerator, c int sd_device_enumerator_add_match_tag(sd_device_enumerator *enumerator, const char *tag); int sd_device_enumerator_add_match_parent(sd_device_enumerator *enumerator, sd_device *parent); int sd_device_enumerator_allow_uninitialized(sd_device_enumerator *enumerator); +int sd_device_enumerator_add_all_parents(sd_device_enumerator *enumerator); /* device monitor */ @@ -142,6 +145,9 @@ int sd_device_monitor_new(sd_device_monitor **ret); sd_device_monitor *sd_device_monitor_ref(sd_device_monitor *m); sd_device_monitor *sd_device_monitor_unref(sd_device_monitor *m); +int sd_device_monitor_get_fd(sd_device_monitor *m); +int sd_device_monitor_get_events(sd_device_monitor *m); +int sd_device_monitor_get_timeout(sd_device_monitor *m, uint64_t *ret); int sd_device_monitor_set_receive_buffer_size(sd_device_monitor *m, size_t size); int sd_device_monitor_attach_event(sd_device_monitor *m, sd_event *event); int sd_device_monitor_detach_event(sd_device_monitor *m); @@ -149,8 +155,10 @@ sd_event *sd_device_monitor_get_event(sd_device_monitor *m); sd_event_source *sd_device_monitor_get_event_source(sd_device_monitor *m); int sd_device_monitor_set_description(sd_device_monitor *m, const char *description); int sd_device_monitor_get_description(sd_device_monitor *m, const char **ret); +int sd_device_monitor_is_running(sd_device_monitor *m); int sd_device_monitor_start(sd_device_monitor *m, sd_device_monitor_handler_t callback, void *userdata); int sd_device_monitor_stop(sd_device_monitor *m); +int sd_device_monitor_receive(sd_device_monitor *m, sd_device **ret); int sd_device_monitor_filter_add_match_subsystem_devtype(sd_device_monitor *m, const char *subsystem, const char *devtype); int sd_device_monitor_filter_add_match_tag(sd_device_monitor *m, const char *tag); diff --git a/src/libnm-systemd-core/src/systemd/sd-dhcp6-lease.h b/src/libnm-systemd-core/src/systemd/sd-dhcp6-lease.h index e18d5781..d6bcceb2 100644 --- a/src/libnm-systemd-core/src/systemd/sd-dhcp6-lease.h +++ b/src/libnm-systemd-core/src/systemd/sd-dhcp6-lease.h @@ -30,6 +30,7 @@ _SD_BEGIN_DECLARATIONS; typedef struct sd_dhcp6_lease sd_dhcp6_lease; +typedef struct sd_dns_resolver sd_dns_resolver; int sd_dhcp6_lease_get_timestamp(sd_dhcp6_lease *lease, clockid_t clock, uint64_t *ret); int sd_dhcp6_lease_get_t1(sd_dhcp6_lease *lease, uint64_t *ret); @@ -74,6 +75,7 @@ int sd_dhcp6_lease_get_pd_lifetime_timestamp( int sd_dhcp6_lease_has_pd_prefix(sd_dhcp6_lease *lease); int sd_dhcp6_lease_get_dns(sd_dhcp6_lease *lease, const struct in6_addr **ret); +int sd_dhcp6_lease_get_dnr(sd_dhcp6_lease *lease, sd_dns_resolver **ret); int sd_dhcp6_lease_get_domains(sd_dhcp6_lease *lease, char ***ret); int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease, const struct in6_addr **ret); int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ret); diff --git a/src/libnm-systemd-core/src/systemd/sd-dhcp6-protocol.h b/src/libnm-systemd-core/src/systemd/sd-dhcp6-protocol.h index 78c80f7c..b1d9ca1f 100644 --- a/src/libnm-systemd-core/src/systemd/sd-dhcp6-protocol.h +++ b/src/libnm-systemd-core/src/systemd/sd-dhcp6-protocol.h @@ -165,8 +165,9 @@ enum { SD_DHCP6_OPTION_SLAP_QUAD = 140, /* RFC 8948 */ SD_DHCP6_OPTION_V6_DOTS_RI = 141, /* RFC 8973 */ SD_DHCP6_OPTION_V6_DOTS_ADDRESS = 142, /* RFC 8973 */ - SD_DHCP6_OPTION_IPV6_ADDRESS_ANDSF = 143 /* RFC 6153 */ - /* option codes 144-65535 are unassigned */ + SD_DHCP6_OPTION_IPV6_ADDRESS_ANDSF = 143, /* RFC 6153 */ + SD_DHCP6_OPTION_V6_DNR = 144 /* RFC 9463 */ + /* option codes 145-65535 are unassigned */ }; _SD_END_DECLARATIONS; diff --git a/src/libnm-systemd-core/src/systemd/sd-event.h b/src/libnm-systemd-core/src/systemd/sd-event.h index 49d69759..1e19dd4e 100644 --- a/src/libnm-systemd-core/src/systemd/sd-event.h +++ b/src/libnm-systemd-core/src/systemd/sd-event.h @@ -108,12 +108,12 @@ int sd_event_run(sd_event *e, uint64_t usec); int sd_event_loop(sd_event *e); int sd_event_exit(sd_event *e, int code); -int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec); +int sd_event_now(sd_event *e, clockid_t clock, uint64_t *ret); int sd_event_get_fd(sd_event *e); int sd_event_get_state(sd_event *e); -int sd_event_get_tid(sd_event *e, pid_t *tid); -int sd_event_get_exit_code(sd_event *e, int *code); +int sd_event_get_tid(sd_event *e, pid_t *ret); +int sd_event_get_exit_code(sd_event *e, int *ret); int sd_event_set_watchdog(sd_event *e, int b); int sd_event_get_watchdog(sd_event *e); int sd_event_get_iteration(sd_event *e, uint64_t *ret); @@ -123,33 +123,33 @@ sd_event_source* sd_event_source_ref(sd_event_source *s); sd_event_source* sd_event_source_unref(sd_event_source *s); sd_event_source* sd_event_source_disable_unref(sd_event_source *s); -sd_event *sd_event_source_get_event(sd_event_source *s); +sd_event* sd_event_source_get_event(sd_event_source *s); void* sd_event_source_get_userdata(sd_event_source *s); void* sd_event_source_set_userdata(sd_event_source *s, void *userdata); int sd_event_source_set_description(sd_event_source *s, const char *description); -int sd_event_source_get_description(sd_event_source *s, const char **description); +int sd_event_source_get_description(sd_event_source *s, const char **ret); int sd_event_source_set_prepare(sd_event_source *s, sd_event_handler_t callback); int sd_event_source_get_pending(sd_event_source *s); -int sd_event_source_get_priority(sd_event_source *s, int64_t *priority); +int sd_event_source_get_priority(sd_event_source *s, int64_t *ret); int sd_event_source_set_priority(sd_event_source *s, int64_t priority); -int sd_event_source_get_enabled(sd_event_source *s, int *enabled); +int sd_event_source_get_enabled(sd_event_source *s, int *ret); int sd_event_source_set_enabled(sd_event_source *s, int enabled); int sd_event_source_get_io_fd(sd_event_source *s); int sd_event_source_set_io_fd(sd_event_source *s, int fd); int sd_event_source_get_io_fd_own(sd_event_source *s); int sd_event_source_set_io_fd_own(sd_event_source *s, int own); -int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events); +int sd_event_source_get_io_events(sd_event_source *s, uint32_t *ret); int sd_event_source_set_io_events(sd_event_source *s, uint32_t events); -int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents); -int sd_event_source_get_time(sd_event_source *s, uint64_t *usec); +int sd_event_source_get_io_revents(sd_event_source *s, uint32_t *ret); +int sd_event_source_get_time(sd_event_source *s, uint64_t *ret); int sd_event_source_set_time(sd_event_source *s, uint64_t usec); int sd_event_source_set_time_relative(sd_event_source *s, uint64_t usec); -int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec); +int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *ret); int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec); -int sd_event_source_get_time_clock(sd_event_source *s, clockid_t *clock); +int sd_event_source_get_time_clock(sd_event_source *s, clockid_t *ret); int sd_event_source_get_signal(sd_event_source *s); -int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid); +int sd_event_source_get_child_pid(sd_event_source *s, pid_t *ret); int sd_event_source_get_child_pidfd(sd_event_source *s); int sd_event_source_get_child_pidfd_own(sd_event_source *s); int sd_event_source_set_child_pidfd_own(sd_event_source *s, int own); @@ -161,6 +161,7 @@ int sd_event_source_send_child_signal(sd_event_source *s, int sig, const siginfo int sd_event_source_send_child_signal(sd_event_source *s, int sig, const void *si, unsigned flags); #endif int sd_event_source_get_inotify_mask(sd_event_source *s, uint32_t *ret); +int sd_event_source_get_inotify_path(sd_event_source *s, const char **ret); int sd_event_source_set_memory_pressure_type(sd_event_source *e, const char *ty); int sd_event_source_set_memory_pressure_period(sd_event_source *s, uint64_t threshold_usec, uint64_t window_usec); int sd_event_source_set_destroy_callback(sd_event_source *s, sd_event_destroy_t callback); diff --git a/src/libnm-systemd-core/src/systemd/sd-id128.h b/src/libnm-systemd-core/src/systemd/sd-id128.h index a984a9d8..7be69040 100644 --- a/src/libnm-systemd-core/src/systemd/sd-id128.h +++ b/src/libnm-systemd-core/src/systemd/sd-id128.h @@ -37,8 +37,8 @@ union sd_id128 { #define SD_ID128_STRING_MAX 33U #define SD_ID128_UUID_STRING_MAX 37U -char *sd_id128_to_string(sd_id128_t id, char s[_SD_ARRAY_STATIC SD_ID128_STRING_MAX]); -char *sd_id128_to_uuid_string(sd_id128_t id, char s[_SD_ARRAY_STATIC SD_ID128_UUID_STRING_MAX]); +char* sd_id128_to_string(sd_id128_t id, char s[_SD_ARRAY_STATIC SD_ID128_STRING_MAX]); +char* sd_id128_to_uuid_string(sd_id128_t id, char s[_SD_ARRAY_STATIC SD_ID128_UUID_STRING_MAX]); int sd_id128_from_string(const char *s, sd_id128_t *ret); #define SD_ID128_TO_STRING(id) sd_id128_to_string((id), (char[SD_ID128_STRING_MAX]) {}) @@ -53,6 +53,7 @@ int sd_id128_get_invocation(sd_id128_t *ret); int sd_id128_get_app_specific(sd_id128_t base, sd_id128_t app_id, sd_id128_t *ret); int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret); int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret); +int sd_id128_get_invocation_app_specific(sd_id128_t app_id, sd_id128_t *ret); #define SD_ID128_ARRAY(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \ { .bytes = { 0x##v0, 0x##v1, 0x##v2, 0x##v3, 0x##v4, 0x##v5, 0x##v6, 0x##v7, \ @@ -116,24 +117,24 @@ int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret); #define SD_ID128_MAKE_UUID_STR(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \ #a #b #c #d "-" #e #f "-" #g #h "-" #i #j "-" #k #l #m #n #o #p -_sd_pure_ static __inline__ int sd_id128_equal(sd_id128_t a, sd_id128_t b) { +_sd_const_ static __inline__ int sd_id128_equal(sd_id128_t a, sd_id128_t b) { return a.qwords[0] == b.qwords[0] && a.qwords[1] == b.qwords[1]; } int sd_id128_string_equal(const char *s, sd_id128_t id); -_sd_pure_ static __inline__ int sd_id128_is_null(sd_id128_t a) { +_sd_const_ static __inline__ int sd_id128_is_null(sd_id128_t a) { return a.qwords[0] == 0 && a.qwords[1] == 0; } -_sd_pure_ static __inline__ int sd_id128_is_allf(sd_id128_t a) { +_sd_const_ static __inline__ int sd_id128_is_allf(sd_id128_t a) { return a.qwords[0] == UINT64_C(0xFFFFFFFFFFFFFFFF) && a.qwords[1] == UINT64_C(0xFFFFFFFFFFFFFFFF); } #define SD_ID128_NULL ((const sd_id128_t) { .qwords = { 0, 0 }}) #define SD_ID128_ALLF ((const sd_id128_t) { .qwords = { UINT64_C(0xFFFFFFFFFFFFFFFF), UINT64_C(0xFFFFFFFFFFFFFFFF) }}) -_sd_pure_ static __inline__ int sd_id128_in_setv(sd_id128_t a, va_list ap) { +_sd_const_ static __inline__ int sd_id128_in_setv(sd_id128_t a, va_list ap) { for (;;) { sd_id128_t b = va_arg(ap, sd_id128_t); @@ -145,7 +146,7 @@ _sd_pure_ static __inline__ int sd_id128_in_setv(sd_id128_t a, va_list ap) { } } -_sd_pure_ static __inline__ int sd_id128_in_set_sentinel(sd_id128_t a, ...) { +_sd_const_ static __inline__ int sd_id128_in_set_sentinel(sd_id128_t a, ...) { va_list ap; int r; diff --git a/src/libnm-systemd-core/src/systemd/sd-ndisc.h b/src/libnm-systemd-core/src/systemd/sd-ndisc.h index 5f4f6caf..85fcf6bc 100644 --- a/src/libnm-systemd-core/src/systemd/sd-ndisc.h +++ b/src/libnm-systemd-core/src/systemd/sd-ndisc.h @@ -26,7 +26,9 @@ #include <sys/types.h> #include "sd-event.h" +#include "sd-ndisc-neighbor.h" #include "sd-ndisc-protocol.h" +#include "sd-ndisc-redirect.h" #include "sd-ndisc-router.h" #include "_sd-common.h" @@ -35,9 +37,11 @@ _SD_BEGIN_DECLARATIONS; typedef struct sd_ndisc sd_ndisc; -__extension__ typedef enum sd_ndisc_event_t { +__extension__ typedef enum _SD_ENUM_TYPE_S64(sd_ndisc_event_t) { SD_NDISC_EVENT_TIMEOUT, SD_NDISC_EVENT_ROUTER, + SD_NDISC_EVENT_NEIGHBOR, + SD_NDISC_EVENT_REDIRECT, _SD_NDISC_EVENT_MAX, _SD_NDISC_EVENT_INVALID = -EINVAL, _SD_ENUM_FORCE_S64(NDISC_EVENT) diff --git a/src/libnm-systemd-shared/meson.build b/src/libnm-systemd-shared/meson.build index c93930f3..7a88d78d 100644 --- a/src/libnm-systemd-shared/meson.build +++ b/src/libnm-systemd-shared/meson.build @@ -5,6 +5,7 @@ libnm_systemd_shared = static_library( sources: files( 'nm-sd-utils-shared.c', 'src/basic/alloc-util.c', + 'src/basic/chattr-util.c', 'src/basic/btrfs.c', 'src/basic/devnum-util.c', 'src/basic/env-file.c', @@ -14,6 +15,7 @@ libnm_systemd_shared = static_library( 'src/basic/extract-word.c', 'src/basic/fd-util.c', 'src/basic/fileio.c', + 'src/basic/format-ifname.c', 'src/basic/format-util.c', 'src/basic/fs-util.c', 'src/basic/glyph-util.c', @@ -31,10 +33,12 @@ libnm_systemd_shared = static_library( 'src/basic/ordered-set.c', 'src/basic/parse-util.c', 'src/basic/path-util.c', + 'src/basic/pidfd-util.c', 'src/basic/prioq.c', 'src/basic/process-util.c', 'src/basic/random-util.c', 'src/basic/ratelimit.c', + 'src/basic/sha256.c', 'src/basic/signal-util.c', 'src/basic/socket-util.c', 'src/basic/stat-util.c', @@ -45,7 +49,7 @@ libnm_systemd_shared = static_library( 'src/basic/time-util.c', 'src/basic/tmpfile-util.c', 'src/basic/utf8.c', - 'src/fundamental/sha256.c', + 'src/fundamental/sha256-fundamental.c', 'src/fundamental/string-util-fundamental.c', 'src/shared/dns-domain.c', 'src/shared/web-util.c', diff --git a/src/libnm-systemd-shared/sd-adapt-shared/dns-resolver-internal.h b/src/libnm-systemd-shared/sd-adapt-shared/dns-resolver-internal.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/dns-resolver-internal.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/keyring-util.h b/src/libnm-systemd-shared/sd-adapt-shared/keyring-util.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/keyring-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/sd-adapt-shared/nm-sd-adapt-shared.h b/src/libnm-systemd-shared/sd-adapt-shared/nm-sd-adapt-shared.h index 83916fb2..e2fd27b8 100644 --- a/src/libnm-systemd-shared/sd-adapt-shared/nm-sd-adapt-shared.h +++ b/src/libnm-systemd-shared/sd-adapt-shared/nm-sd-adapt-shared.h @@ -116,6 +116,11 @@ raw_getpid(void) #define ALTIFNAMSIZ 128 #endif +/* kernel cb12fd8e0dabb9a1c8aef55a6a41e2c255fcdf4b (6.8) */ +#ifndef PID_FS_MAGIC +#define PID_FS_MAGIC 0x50494446 +#endif + #define HAVE_LINUX_TIME_TYPES_H 0 #ifndef __COMPAR_FN_T diff --git a/src/libnm-systemd-shared/sd-adapt-shared/syslog-util.h b/src/libnm-systemd-shared/sd-adapt-shared/syslog-util.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/libnm-systemd-shared/sd-adapt-shared/syslog-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/libnm-systemd-shared/src/basic/alloc-util.c b/src/libnm-systemd-shared/src/basic/alloc-util.c index 243ff521..f9686666 100644 --- a/src/libnm-systemd-shared/src/basic/alloc-util.c +++ b/src/libnm-systemd-shared/src/basic/alloc-util.c @@ -45,7 +45,7 @@ void* greedy_realloc( size_t need, size_t size) { - size_t a, newalloc; + size_t newalloc; void *q; assert(p); @@ -62,14 +62,13 @@ void* greedy_realloc( return NULL; newalloc = need * 2; - if (size_multiply_overflow(newalloc, size)) + if (!MUL_ASSIGN_SAFE(&newalloc, size)) return NULL; - a = newalloc * size; - if (a < 64) /* Allocate at least 64 bytes */ - a = 64; + if (newalloc < 64) /* Allocate at least 64 bytes */ + newalloc = 64; - q = realloc(*p, a); + q = realloc(*p, newalloc); if (!q) return NULL; diff --git a/src/libnm-systemd-shared/src/basic/alloc-util.h b/src/libnm-systemd-shared/src/basic/alloc-util.h index c215c33f..ba712982 100644 --- a/src/libnm-systemd-shared/src/basic/alloc-util.h +++ b/src/libnm-systemd-shared/src/basic/alloc-util.h @@ -26,23 +26,23 @@ typedef void* (*mfree_func_t)(void *p); #define alloca_safe(n) \ ({ \ - size_t _nn_ = n; \ + size_t _nn_ = (n); \ assert(_nn_ <= ALLOCA_MAX); \ alloca(_nn_ == 0 ? 1 : _nn_); \ }) \ #define newa(t, n) \ ({ \ - size_t _n_ = n; \ - assert(!size_multiply_overflow(sizeof(t), _n_)); \ - (t*) alloca_safe(sizeof(t)*_n_); \ + size_t _n_ = (n); \ + assert_se(MUL_ASSIGN_SAFE(&_n_, sizeof(t))); \ + (t*) alloca_safe(_n_); \ }) #define newa0(t, n) \ ({ \ - size_t _n_ = n; \ - assert(!size_multiply_overflow(sizeof(t), _n_)); \ - (t*) alloca0((sizeof(t)*_n_)); \ + size_t _n_ = (n); \ + assert_se(MUL_ASSIGN_SAFE(&_n_, sizeof(t))); \ + (t*) alloca0(_n_); \ }) #define newdup(t, p, n) ((t*) memdup_multiply(p, n, sizeof(t))) @@ -155,7 +155,10 @@ void* greedy_realloc_append(void **p, size_t *n_p, const void *from, size_t n_fr greedy_realloc0((void**) &(array), (need), sizeof((array)[0])) #define GREEDY_REALLOC_APPEND(array, n_array, from, n_from) \ - greedy_realloc_append((void**) &(array), (size_t*) &(n_array), (from), (n_from), sizeof((array)[0])) + ({ \ + const typeof(*(array)) *_from_ = (from); \ + greedy_realloc_append((void**) &(array), &(n_array), _from_, (n_from), sizeof((array)[0])); \ + }) #define alloca0(n) \ ({ \ diff --git a/src/libnm-systemd-shared/src/basic/arphrd-util.h b/src/libnm-systemd-shared/src/basic/arphrd-util.h index 33f5694a..0fd75a04 100644 --- a/src/libnm-systemd-shared/src/basic/arphrd-util.h +++ b/src/libnm-systemd-shared/src/basic/arphrd-util.h @@ -4,7 +4,7 @@ #include <inttypes.h> #include <stddef.h> -const char *arphrd_to_name(int id); +const char* arphrd_to_name(int id); int arphrd_from_name(const char *name); size_t arphrd_to_hw_addr_len(uint16_t arphrd); diff --git a/src/libnm-systemd-shared/src/basic/bitfield.h b/src/libnm-systemd-shared/src/basic/bitfield.h new file mode 100644 index 00000000..048e08d7 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/bitfield.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "macro.h" + +/* Bit index (0-based) to mask of specified type. Assertion failure if index is out of range. */ +#define _INDEX_TO_MASK(type, i, uniq) \ + ({ \ + int UNIQ_T(_i, uniq) = (i); \ + assert(UNIQ_T(_i, uniq) < (int)sizeof(type) * 8); \ + ((type)1) << UNIQ_T(_i, uniq); \ + }) +#define INDEX_TO_MASK(type, i) \ + ({ \ + assert_cc(sizeof(type) <= sizeof(unsigned long long)); \ + assert_cc(__builtin_choose_expr(__builtin_constant_p(i), i, 0) < (int)(sizeof(type) * 8)); \ + __builtin_choose_expr(__builtin_constant_p(i), \ + ((type)1) << (i), \ + _INDEX_TO_MASK(type, i, UNIQ)); \ + }) + +/* Builds a mask of specified type with multiple bits set. Note the result will not be constant, even if all + * indexes are constant. */ +#define INDEXES_TO_MASK(type, ...) \ + UNIQ_INDEXES_TO_MASK(type, UNIQ, ##__VA_ARGS__) +#define UNIQ_INDEXES_TO_MASK(type, uniq, ...) \ + ({ \ + typeof(type) UNIQ_T(_mask, uniq) = (type)0; \ + int UNIQ_T(_i, uniq); \ + FOREACH_ARGUMENT(UNIQ_T(_i, uniq), ##__VA_ARGS__) \ + UNIQ_T(_mask, uniq) |= INDEX_TO_MASK(type, UNIQ_T(_i, uniq)); \ + UNIQ_T(_mask, uniq); \ + }) + +/* Same as the FLAG macros, but accept a 0-based bit index instead of a mask. Results in assertion failure if + * index is out of range for the type. */ +#define SET_BIT(bits, i) SET_FLAG(bits, INDEX_TO_MASK(typeof(bits), i), true) +#define CLEAR_BIT(bits, i) SET_FLAG(bits, INDEX_TO_MASK(typeof(bits), i), false) +#define BIT_SET(bits, i) FLAGS_SET(bits, INDEX_TO_MASK(typeof(bits), i)) + +/* As above, but accepts multiple indexes. Note the result will not be constant, even if all indexes are + * constant. */ +#define SET_BITS(bits, ...) SET_FLAG(bits, INDEXES_TO_MASK(typeof(bits), ##__VA_ARGS__), true) +#define CLEAR_BITS(bits, ...) SET_FLAG(bits, INDEXES_TO_MASK(typeof(bits), ##__VA_ARGS__), false) +#define BITS_SET(bits, ...) FLAGS_SET(bits, INDEXES_TO_MASK(typeof(bits), ##__VA_ARGS__)) + +/* Iterate through each set bit. Index is 0-based and type int. */ +#define BIT_FOREACH(index, bits) _BIT_FOREACH(index, bits, UNIQ) +#define _BIT_FOREACH(index, bits, uniq) \ + for (int UNIQ_T(_last, uniq) = -1, index; \ + (index = BIT_NEXT_SET(bits, UNIQ_T(_last, uniq))) >= 0; \ + UNIQ_T(_last, uniq) = index) + +/* Find the next set bit after 0-based index 'prev'. Result is 0-based index of next set bit, or -1 if no + * more bits are set. */ +#define BIT_FIRST_SET(bits) BIT_NEXT_SET(bits, -1) +#define BIT_NEXT_SET(bits, prev) \ + UNIQ_BIT_NEXT_SET(bits, prev, UNIQ) +#define UNIQ_BIT_NEXT_SET(bits, prev, uniq) \ + ({ \ + typeof(bits) UNIQ_T(_bits, uniq) = (bits); \ + int UNIQ_T(_prev, uniq) = (prev); \ + int UNIQ_T(_next, uniq); \ + _BIT_NEXT_SET(UNIQ_T(_bits, uniq), \ + UNIQ_T(_prev, uniq), \ + UNIQ_T(_next, uniq)); \ + }) +#define _BIT_NEXT_SET(bits, prev, next) \ + ((int)(prev + 1) == (int)sizeof(bits) * 8 \ + ? -1 /* Prev index was msb. */ \ + : ((next = __builtin_ffsll(((unsigned long long)(bits)) >> (prev + 1))) == 0 \ + ? -1 /* No more bits set. */ \ + : prev + next)) diff --git a/src/libnm-systemd-shared/src/basic/cgroup-util.h b/src/libnm-systemd-shared/src/basic/cgroup-util.h index 244f3b65..77294779 100644 --- a/src/libnm-systemd-shared/src/basic/cgroup-util.h +++ b/src/libnm-systemd-shared/src/basic/cgroup-util.h @@ -180,20 +180,33 @@ typedef enum CGroupUnified { * generate paths with multiple adjacent / removed. */ +int cg_path_open(const char *controller, const char *path); +int cg_cgroupid_open(int fsfd, uint64_t id); + +int cg_path_from_cgroupid(int cgroupfs_fd, uint64_t id, char **ret); +int cg_get_cgroupid_at(int dfd, const char *path, uint64_t *ret); +static inline int cg_path_get_cgroupid(const char *path, uint64_t *ret) { + return cg_get_cgroupid_at(AT_FDCWD, path, ret); +} +static inline int cg_fd_get_cgroupid(int fd, uint64_t *ret) { + return cg_get_cgroupid_at(fd, NULL, ret); +} + +typedef enum CGroupFlags { + CGROUP_SIGCONT = 1 << 0, + CGROUP_IGNORE_SELF = 1 << 1, + CGROUP_DONT_SKIP_UNMAPPED = 1 << 2, + CGROUP_NO_PIDFD = 1 << 3, +} CGroupFlags; + int cg_enumerate_processes(const char *controller, const char *path, FILE **ret); -int cg_read_pid(FILE *f, pid_t *ret); -int cg_read_pidref(FILE *f, PidRef *ret); +int cg_read_pid(FILE *f, pid_t *ret, CGroupFlags flags); +int cg_read_pidref(FILE *f, PidRef *ret, CGroupFlags flags); int cg_read_event(const char *controller, const char *path, const char *event, char **ret); int cg_enumerate_subgroups(const char *controller, const char *path, DIR **ret); int cg_read_subgroup(DIR *d, char **ret); -typedef enum CGroupFlags { - CGROUP_SIGCONT = 1 << 0, - CGROUP_IGNORE_SELF = 1 << 1, - CGROUP_REMOVE = 1 << 2, -} CGroupFlags; - typedef int (*cg_kill_log_func_t)(const PidRef *pid, int sig, void *userdata); int cg_kill(const char *path, int sig, CGroupFlags flags, Set *s, cg_kill_log_func_t kill_log, void *userdata); @@ -209,8 +222,6 @@ int cg_get_path_and_check(const char *controller, const char *path, const char * int cg_pid_get_path(const char *controller, pid_t pid, char **ret); int cg_pidref_get_path(const char *controller, const PidRef *pidref, char **ret); -int cg_rmdir(const char *controller, const char *path); - int cg_is_threaded(const char *path); int cg_is_delegated(const char *path); @@ -258,15 +269,11 @@ int cg_get_xattr_malloc(const char *path, const char *name, char **ret); int cg_get_xattr_bool(const char *path, const char *name); int cg_remove_xattr(const char *path, const char *name); -int cg_install_release_agent(const char *controller, const char *agent); -int cg_uninstall_release_agent(const char *controller); - int cg_is_empty(const char *controller, const char *path); int cg_is_empty_recursive(const char *controller, const char *path); int cg_get_root_path(char **path); -int cg_path_get_cgroupid(const char *path, uint64_t *ret); int cg_path_get_session(const char *path, char **ret_session); int cg_path_get_owner_uid(const char *path, uid_t *ret_uid); int cg_path_get_unit(const char *path, char **ret_unit); @@ -280,7 +287,9 @@ int cg_shift_path(const char *cgroup, const char *cached_root, const char **ret_ int cg_pid_get_path_shifted(pid_t pid, const char *cached_root, char **ret_cgroup); int cg_pid_get_session(pid_t pid, char **ret_session); +int cg_pidref_get_session(const PidRef *pidref, char **ret); int cg_pid_get_owner_uid(pid_t pid, uid_t *ret_uid); +int cg_pidref_get_owner_uid(const PidRef *pidref, uid_t *ret); int cg_pid_get_unit(pid_t pid, char **ret_unit); int cg_pidref_get_unit(const PidRef *pidref, char **ret); int cg_pid_get_user_unit(pid_t pid, char **ret_unit); @@ -292,14 +301,12 @@ int cg_path_decode_unit(const char *cgroup, char **ret_unit); bool cg_needs_escape(const char *p); int cg_escape(const char *p, char **ret); -char *cg_unescape(const char *p) _pure_; +char* cg_unescape(const char *p) _pure_; bool cg_controller_is_valid(const char *p); int cg_slice_to_path(const char *unit, char **ret); -typedef const char* (*cg_migrate_callback_t)(CGroupMask mask, void *userdata); - int cg_mask_supported(CGroupMask *ret); int cg_mask_supported_subtree(const char *root, CGroupMask *ret); int cg_mask_from_string(const char *s, CGroupMask *ret); @@ -352,5 +359,10 @@ typedef union { uint8_t space[offsetof(struct file_handle, f_handle) + sizeof(uint64_t)]; } cg_file_handle; -#define CG_FILE_HANDLE_INIT { .file_handle.handle_bytes = sizeof(uint64_t) } +#define CG_FILE_HANDLE_INIT \ + (cg_file_handle) { \ + .file_handle.handle_bytes = sizeof(uint64_t), \ + .file_handle.handle_type = FILEID_KERNFS, \ + } + #define CG_FILE_HANDLE_CGROUPID(fh) (*(uint64_t*) (fh).file_handle.f_handle) diff --git a/src/libnm-systemd-shared/src/basic/chase.h b/src/libnm-systemd-shared/src/basic/chase.h index cfc714b9..eda7cad0 100644 --- a/src/libnm-systemd-shared/src/basic/chase.h +++ b/src/libnm-systemd-shared/src/basic/chase.h @@ -27,12 +27,10 @@ typedef enum ChaseFlags { * also points to the result path even if this flag is set. * When this specified, chase() will succeed with 1 even if the * file points to the last path component does not exist. */ - CHASE_MKDIR_0755 = 1 << 11, /* Create any missing parent directories in the given path. This - * needs to be set with CHASE_NONEXISTENT and/or CHASE_PARENT. - * Note, chase_and_open() or friends always add CHASE_PARENT flag - * when internally call chase(), hence CHASE_MKDIR_0755 can be - * safely set without CHASE_NONEXISTENT and CHASE_PARENT. */ + CHASE_MKDIR_0755 = 1 << 11, /* Create any missing directories in the given path. */ CHASE_EXTRACT_FILENAME = 1 << 12, /* Only return the last component of the resolved path */ + CHASE_MUST_BE_DIRECTORY = 1 << 13, /* Fail if returned inode fd is not a dir */ + CHASE_MUST_BE_REGULAR = 1 << 14, /* Fail if returned inode fd is not a regular file */ } ChaseFlags; bool unsafe_transition(const struct stat *a, const struct stat *b); diff --git a/src/libnm-systemd-shared/src/basic/chattr-util.c b/src/libnm-systemd-shared/src/basic/chattr-util.c new file mode 100644 index 00000000..2a63e46d --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/chattr-util.c @@ -0,0 +1,176 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include <errno.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <linux/fs.h> + +#include "bitfield.h" +#include "chattr-util.h" +#include "errno-util.h" +#include "fd-util.h" +#include "fs-util.h" +#include "macro.h" +#include "string-util.h" + +int chattr_full( + int dir_fd, + const char *path, + unsigned value, + unsigned mask, + unsigned *ret_previous, + unsigned *ret_final, + ChattrApplyFlags flags) { + + _cleanup_close_ int fd = -EBADF; + unsigned old_attr, new_attr; + int set_flags_errno = 0; + struct stat st; + + assert(dir_fd >= 0 || dir_fd == AT_FDCWD); + + fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); + if (fd < 0) + return fd; + + if (fstat(fd, &st) < 0) + return -errno; + + /* Explicitly check whether this is a regular file or directory. If it is anything else (such + * as a device node or fifo), then the ioctl will not hit the file systems but possibly + * drivers, where the ioctl might have different effects. Notably, DRM is using the same + * ioctl() number. */ + + if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode)) + return -ENOTTY; + + if (mask == 0 && !ret_previous && !ret_final) + return 0; + + if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0) + return -errno; + + new_attr = (old_attr & ~mask) | (value & mask); + if (new_attr == old_attr) { + if (ret_previous) + *ret_previous = old_attr; + if (ret_final) + *ret_final = old_attr; + return 0; + } + + if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) >= 0) { + unsigned attr; + + /* Some filesystems (BTRFS) silently fail when a flag cannot be set. Let's make sure our + * changes actually went through by querying the flags again and verifying they're equal to + * the flags we tried to configure. */ + + if (ioctl(fd, FS_IOC_GETFLAGS, &attr) < 0) + return -errno; + + if (new_attr == attr) { + if (ret_previous) + *ret_previous = old_attr; + if (ret_final) + *ret_final = new_attr; + return 1; + } + + /* Trigger the fallback logic. */ + errno = EINVAL; + } + + if ((errno != EINVAL && !ERRNO_IS_NOT_SUPPORTED(errno)) || + !FLAGS_SET(flags, CHATTR_FALLBACK_BITWISE)) + return -errno; + + /* When -EINVAL is returned, we assume that incompatible attributes are simultaneously + * specified. E.g., compress(c) and nocow(C) attributes cannot be set to files on btrfs. + * As a fallback, let's try to set attributes one by one. + * + * Also, when we get EOPNOTSUPP (or a similar error code) we assume a flag might just not be + * supported, and we can ignore it too */ + + unsigned current_attr = old_attr; + + BIT_FOREACH(i, mask) { + unsigned new_one, mask_one = 1u << i; + + new_one = UPDATE_FLAG(current_attr, mask_one, FLAGS_SET(value, mask_one)); + if (new_one == current_attr) + continue; + + if (ioctl(fd, FS_IOC_SETFLAGS, &new_one) < 0) { + if (!ERRNO_IS_IOCTL_NOT_SUPPORTED(errno)) + return -errno; + + log_full_errno(FLAGS_SET(flags, CHATTR_WARN_UNSUPPORTED_FLAGS) ? LOG_WARNING : LOG_DEBUG, + errno, + "Unable to set file attribute 0x%x on %s, ignoring: %m", mask_one, strna(path)); + + /* Ensures that we record whether only EOPNOTSUPP&friends are encountered, or if a more serious + * error (thus worth logging at a different level, etc) was seen too. */ + if (set_flags_errno == 0 || !ERRNO_IS_NOT_SUPPORTED(errno)) + set_flags_errno = -errno; + + continue; + } + + if (ioctl(fd, FS_IOC_GETFLAGS, ¤t_attr) < 0) + return -errno; + } + + if (ret_previous) + *ret_previous = old_attr; + if (ret_final) + *ret_final = current_attr; + + /* -ENOANO indicates that some attributes cannot be set. ERRNO_IS_NOT_SUPPORTED indicates that all + * encountered failures were due to flags not supported by the FS, so return a specific error in + * that case, so callers can handle it properly (e.g.: tmpfiles.d can use debug level logging). */ + return current_attr == new_attr ? 1 : ERRNO_IS_NOT_SUPPORTED(set_flags_errno) ? set_flags_errno : -ENOANO; +} + +int read_attr_fd(int fd, unsigned *ret) { + struct stat st; + + assert(fd >= 0); + assert(ret); + + if (fstat(fd, &st) < 0) + return -errno; + + if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode)) + return -ENOTTY; + + _cleanup_close_ int fd_close = -EBADF; + fd = fd_reopen_condition(fd, O_RDONLY|O_CLOEXEC|O_NOCTTY, O_PATH, &fd_close); /* drop O_PATH if it is set */ + if (fd < 0) + return fd; + + return RET_NERRNO(ioctl(fd, FS_IOC_GETFLAGS, ret)); +} + +int read_attr_at(int dir_fd, const char *path, unsigned *ret) { + _cleanup_close_ int fd_close = -EBADF; + int fd; + + assert(dir_fd >= 0 || dir_fd == AT_FDCWD); + assert(ret); + + if (isempty(path) && dir_fd != AT_FDCWD) + fd = dir_fd; + else { + fd_close = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); + if (fd_close < 0) + return fd_close; + + fd = fd_close; + } + + return read_attr_fd(fd, ret); +} diff --git a/src/libnm-systemd-shared/src/basic/chattr-util.h b/src/libnm-systemd-shared/src/basic/chattr-util.h new file mode 100644 index 00000000..1fe38e32 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/chattr-util.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include <fcntl.h> +#include <linux/fs.h> +#include <stdbool.h> +#include <stddef.h> + +#include "missing_fs.h" + +/* The chattr() flags to apply when creating a new file *before* writing to it. In particular, flags such as + * FS_NOCOW_FL don't work if applied a-posteriori. All other flags are fine (or even necessary, think + * FS_IMMUTABLE_FL!) to apply after writing to the files. */ +#define CHATTR_EARLY_FL \ + (FS_NOATIME_FL | \ + FS_COMPR_FL | \ + FS_NOCOW_FL | \ + FS_NOCOMP_FL | \ + FS_PROJINHERIT_FL) + +#define CHATTR_ALL_FL \ + (FS_NOATIME_FL | \ + FS_SYNC_FL | \ + FS_DIRSYNC_FL | \ + FS_APPEND_FL | \ + FS_COMPR_FL | \ + FS_NODUMP_FL | \ + FS_EXTENT_FL | \ + FS_IMMUTABLE_FL | \ + FS_JOURNAL_DATA_FL | \ + FS_SECRM_FL | \ + FS_UNRM_FL | \ + FS_NOTAIL_FL | \ + FS_TOPDIR_FL | \ + FS_NOCOW_FL | \ + FS_PROJINHERIT_FL) + +typedef enum ChattrApplyFlags { + CHATTR_FALLBACK_BITWISE = 1 << 0, + CHATTR_WARN_UNSUPPORTED_FLAGS = 1 << 1, +} ChattrApplyFlags; + +int chattr_full(int dir_fd, const char *path, unsigned value, unsigned mask, unsigned *ret_previous, unsigned *ret_final, ChattrApplyFlags flags); +static inline int chattr_at(int dir_fd, const char *path, unsigned value, unsigned mask, unsigned *previous) { + return chattr_full(dir_fd, path, value, mask, previous, NULL, 0); +} +static inline int chattr_fd(int fd, unsigned value, unsigned mask, unsigned *previous) { + return chattr_full(fd, NULL, value, mask, previous, NULL, 0); +} +static inline int chattr_path(const char *path, unsigned value, unsigned mask, unsigned *previous) { + return chattr_full(AT_FDCWD, path, value, mask, previous, NULL, 0); +} + +int read_attr_fd(int fd, unsigned *ret); +int read_attr_at(int dir_fd, const char *path, unsigned *ret); + +/* Combination of chattr flags, that should be appropriate for secrets stored on disk: Secure Remove + + * Exclusion from Dumping + Synchronous Writing (i.e. not caching in memory) + In-Place Updating (i.e. not + * spurious copies). */ +#define CHATTR_SECRET_FLAGS (FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL) + +static inline int chattr_secret(int fd, ChattrApplyFlags flags) { + return chattr_full(fd, NULL, CHATTR_SECRET_FLAGS, CHATTR_SECRET_FLAGS, NULL, NULL, flags|CHATTR_FALLBACK_BITWISE); +} diff --git a/src/libnm-systemd-shared/src/basic/constants.h b/src/libnm-systemd-shared/src/basic/constants.h index 6bb5f3c2..93e6efbd 100644 --- a/src/libnm-systemd-shared/src/basic/constants.h +++ b/src/libnm-systemd-shared/src/basic/constants.h @@ -42,9 +42,6 @@ #define DEFAULT_START_LIMIT_INTERVAL (10*USEC_PER_SEC) #define DEFAULT_START_LIMIT_BURST 5 -/* Wait for 1.5 seconds at maximum for freeze operation */ -#define FREEZE_TIMEOUT (1500 * USEC_PER_MSEC) - /* The default time after which exit-on-idle services exit. This * should be kept lower than the watchdog timeout, because otherwise * the watchdog pings will keep the loop busy. */ @@ -67,18 +64,12 @@ "/usr/local/lib/" n "\0" \ "/usr/lib/" n "\0" -#define CONF_PATHS_USR(n) \ +#define CONF_PATHS(n) \ "/etc/" n, \ "/run/" n, \ "/usr/local/lib/" n, \ "/usr/lib/" n -#define CONF_PATHS(n) \ - CONF_PATHS_USR(n) - -#define CONF_PATHS_USR_STRV(n) \ - STRV_MAKE(CONF_PATHS_USR(n)) - #define CONF_PATHS_STRV(n) \ STRV_MAKE(CONF_PATHS(n)) @@ -94,4 +85,5 @@ /* Path where systemd-oomd listens for varlink connections from user managers to report changes in ManagedOOM settings. */ #define VARLINK_ADDR_PATH_MANAGED_OOM_USER "/run/systemd/oom/io.systemd.ManagedOOM" -#define KERNEL_BASELINE_VERSION "4.15" +/* Recommended baseline - see README for details */ +#define KERNEL_BASELINE_VERSION "5.7" diff --git a/src/libnm-systemd-shared/src/basic/devnum-util.c b/src/libnm-systemd-shared/src/basic/devnum-util.c index b13c9fc6..f2c7c2d9 100644 --- a/src/libnm-systemd-shared/src/basic/devnum-util.c +++ b/src/libnm-systemd-shared/src/basic/devnum-util.c @@ -60,21 +60,18 @@ int device_path_make_major_minor(mode_t mode, dev_t devnum, char **ret) { } int device_path_make_inaccessible(mode_t mode, char **ret) { - char *s; + const char *s; assert(ret); if (S_ISCHR(mode)) - s = strdup("/run/systemd/inaccessible/chr"); + s = "/run/systemd/inaccessible/chr"; else if (S_ISBLK(mode)) - s = strdup("/run/systemd/inaccessible/blk"); + s = "/run/systemd/inaccessible/blk"; else return -ENODEV; - if (!s) - return -ENOMEM; - *ret = s; - return 0; + return strdup_to(ret, s); } #if 0 /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/env-util.c b/src/libnm-systemd-shared/src/basic/env-util.c index 54509a55..2fe7332c 100644 --- a/src/libnm-systemd-shared/src/basic/env-util.c +++ b/src/libnm-systemd-shared/src/basic/env-util.c @@ -20,6 +20,7 @@ #include "stdio-util.h" #include "string-util.h" #include "strv.h" +#include "syslog-util.h" #include "utf8.h" #if 0 /* NM_IGNORED */ @@ -268,7 +269,7 @@ static bool env_entry_has_name(const char *entry, const char *name) { return *t == '='; } -char **strv_env_delete(char **x, size_t n_lists, ...) { +char** strv_env_delete(char **x, size_t n_lists, ...) { size_t n, i = 0; _cleanup_strv_free_ char **t = NULL; va_list ap; @@ -555,7 +556,7 @@ char* strv_env_get_n(char * const *l, const char *name, size_t k, ReplaceEnvFlag } #endif /* NM_IGNORED */ -char *strv_env_pairs_get(char **l, const char *name) { +char* strv_env_pairs_get(char **l, const char *name) { char *result = NULL; assert(name); @@ -568,7 +569,35 @@ char *strv_env_pairs_get(char **l, const char *name) { } #if 0 /* NM_IGNORED */ -char **strv_env_clean_with_callback(char **e, void (*invalid_callback)(const char *p, void *userdata), void *userdata) { +int strv_env_get_merged(char **l, char ***ret) { + _cleanup_strv_free_ char **v = NULL; + size_t n = 0; + int r; + + assert(ret); + + /* This converts a strv with pairs of environment variable name + value into a strv of name and + * value concatenated with a "=" separator. E.g. + * input : { "NAME", "value", "FOO", "var" } + * output : { "NAME=value", "FOO=var" } */ + + STRV_FOREACH_PAIR(key, value, l) { + char *s; + + s = strjoin(*key, "=", *value); + if (!s) + return -ENOMEM; + + r = strv_consume_with_size(&v, &n, s); + if (r < 0) + return r; + } + + *ret = TAKE_PTR(v); + return 0; +} + +char** strv_env_clean_with_callback(char **e, void (*invalid_callback)(const char *p, void *userdata), void *userdata) { int k = 0; STRV_FOREACH(p, e) { @@ -800,10 +829,10 @@ int replace_env_full( t = v; } - r = strv_extend_strv(&unset_variables, u, /* filter_duplicates= */ true); + r = strv_extend_strv_consume(&unset_variables, TAKE_PTR(u), /* filter_duplicates= */ true); if (r < 0) return r; - r = strv_extend_strv(&bad_variables, b, /* filter_duplicates= */ true); + r = strv_extend_strv_consume(&bad_variables, TAKE_PTR(b), /* filter_duplicates= */ true); if (r < 0) return r; @@ -935,21 +964,21 @@ int replace_env_argv( return r; n[++k] = NULL; - r = strv_extend_strv(&unset_variables, u, /* filter_duplicates= */ true); + r = strv_extend_strv_consume(&unset_variables, TAKE_PTR(u), /* filter_duplicates= */ true); if (r < 0) return r; - r = strv_extend_strv(&bad_variables, b, /*filter_duplicates= */ true); + r = strv_extend_strv_consume(&bad_variables, TAKE_PTR(b), /* filter_duplicates= */ true); if (r < 0) return r; } if (ret_unset_variables) { - strv_uniq(strv_sort(unset_variables)); + strv_sort_uniq(unset_variables); *ret_unset_variables = TAKE_PTR(unset_variables); } if (ret_bad_variables) { - strv_uniq(strv_sort(bad_variables)); + strv_sort_uniq(bad_variables); *ret_bad_variables = TAKE_PTR(bad_variables); } @@ -1146,14 +1175,17 @@ int setenvf(const char *name, bool overwrite, const char *valuef, ...) { return RET_NERRNO(unsetenv(name)); va_start(ap, valuef); - DISABLE_WARNING_FORMAT_NONLITERAL; r = vasprintf(&value, valuef, ap); - REENABLE_WARNING; va_end(ap); if (r < 0) return -ENOMEM; + /* Try to suppress writes if the value is already set correctly (simply because memory management of + * environment variables sucks a bit. */ + if (streq_ptr(getenv(name), value)) + return 0; + return RET_NERRNO(setenv(name, value, overwrite)); } #endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/env-util.h b/src/libnm-systemd-shared/src/basic/env-util.h index 6610ca8c..203ed65b 100644 --- a/src/libnm-systemd-shared/src/basic/env-util.h +++ b/src/libnm-systemd-shared/src/basic/env-util.h @@ -34,14 +34,14 @@ int replace_env_argv(char **argv, char **env, char ***ret, char ***ret_unset_var bool strv_env_is_valid(char **e); #define strv_env_clean(l) strv_env_clean_with_callback(l, NULL, NULL) -char **strv_env_clean_with_callback(char **l, void (*invalid_callback)(const char *p, void *userdata), void *userdata); +char** strv_env_clean_with_callback(char **l, void (*invalid_callback)(const char *p, void *userdata), void *userdata); bool strv_env_name_is_valid(char **l); bool strv_env_name_or_assignment_is_valid(char **l); char** _strv_env_merge(char **first, ...); #define strv_env_merge(first, ...) _strv_env_merge(first, __VA_ARGS__, POINTER_MAX) -char **strv_env_delete(char **x, size_t n_lists, ...); /* New copy */ +char** strv_env_delete(char **x, size_t n_lists, ...); /* New copy */ char** strv_env_unset(char **l, const char *p); /* In place ... */ char** strv_env_unset_many_internal(char **l, ...) _sentinel_; @@ -59,7 +59,8 @@ static inline char* strv_env_get(char * const *x, const char *n) { return strv_env_get_n(x, n, SIZE_MAX, 0); } -char *strv_env_pairs_get(char **l, const char *name) _pure_; +char* strv_env_pairs_get(char **l, const char *name) _pure_; +int strv_env_get_merged(char **l, char ***ret); int getenv_bool(const char *p); int secure_getenv_bool(const char *p); diff --git a/src/libnm-systemd-shared/src/basic/errno-util.h b/src/libnm-systemd-shared/src/basic/errno-util.h index 27804e63..02572e3b 100644 --- a/src/libnm-systemd-shared/src/basic/errno-util.h +++ b/src/libnm-systemd-shared/src/basic/errno-util.h @@ -158,7 +158,7 @@ static inline bool ERRNO_IS_NEG_RESOURCE(intmax_t r) { } _DEFINE_ABS_WRAPPER(RESOURCE); -/* Seven different errors for "operation/system call/ioctl/socket feature not supported" */ +/* Seven different errors for "operation/system call/socket feature not supported" */ static inline bool ERRNO_IS_NEG_NOT_SUPPORTED(intmax_t r) { return IN_SET(r, -EOPNOTSUPP, @@ -167,10 +167,17 @@ static inline bool ERRNO_IS_NEG_NOT_SUPPORTED(intmax_t r) { -EAFNOSUPPORT, -EPFNOSUPPORT, -EPROTONOSUPPORT, - -ESOCKTNOSUPPORT); + -ESOCKTNOSUPPORT, + -ENOPROTOOPT); } _DEFINE_ABS_WRAPPER(NOT_SUPPORTED); +/* ioctl() with unsupported command/arg might additionally return EINVAL */ +static inline bool ERRNO_IS_NEG_IOCTL_NOT_SUPPORTED(intmax_t r) { + return ERRNO_IS_NEG_NOT_SUPPORTED(r) || r == -EINVAL; +} +_DEFINE_ABS_WRAPPER(IOCTL_NOT_SUPPORTED); + /* Two different errors for access problems */ static inline bool ERRNO_IS_NEG_PRIVILEGE(intmax_t r) { return IN_SET(r, diff --git a/src/libnm-systemd-shared/src/basic/escape.c b/src/libnm-systemd-shared/src/basic/escape.c index 29f8b9cd..e882aced 100644 --- a/src/libnm-systemd-shared/src/basic/escape.c +++ b/src/libnm-systemd-shared/src/basic/escape.c @@ -368,6 +368,8 @@ char* xescape_full(const char *s, const char *bad, size_t console_width, XEscape char *ans, *t, *prev, *prev2; const char *f; + assert(s); + /* Escapes all chars in bad, in addition to \ and all special chars, in \xFF style escaping. May be * reversed with cunescape(). If XESCAPE_8_BIT is specified, characters >= 127 are let through * unchanged. This corresponds to non-ASCII printable characters in pre-unicode encodings. @@ -400,7 +402,7 @@ char* xescape_full(const char *s, const char *bad, size_t console_width, XEscape if ((unsigned char) *f < ' ' || (!FLAGS_SET(flags, XESCAPE_8_BIT) && (unsigned char) *f >= 127) || - *f == '\\' || strchr(bad, *f)) { + *f == '\\' || (bad && strchr(bad, *f))) { if ((size_t) (t - ans) + 4 + 3 * force_ellipsis > console_width) break; @@ -440,7 +442,7 @@ char* xescape_full(const char *s, const char *bad, size_t console_width, XEscape char* escape_non_printable_full(const char *str, size_t console_width, XEscapeFlags flags) { if (FLAGS_SET(flags, XESCAPE_8_BIT)) - return xescape_full(str, "", console_width, flags); + return xescape_full(str, /* bad= */ NULL, console_width, flags); else return utf8_escape_non_printable_full(str, console_width, @@ -454,6 +456,12 @@ char* octescape(const char *s, size_t len) { assert(s || len == 0); + if (len == SIZE_MAX) + len = strlen(s); + + if (len > (SIZE_MAX - 1) / 4) + return NULL; + t = buf = new(char, len * 4 + 1); if (!buf) return NULL; diff --git a/src/libnm-systemd-shared/src/basic/ether-addr-util.c b/src/libnm-systemd-shared/src/basic/ether-addr-util.c index 1eb2e700..2643c974 100644 --- a/src/libnm-systemd-shared/src/basic/ether-addr-util.c +++ b/src/libnm-systemd-shared/src/basic/ether-addr-util.c @@ -13,7 +13,7 @@ #include "macro.h" #include "string-util.h" -char *hw_addr_to_string_full( +char* hw_addr_to_string_full( const struct hw_addr_data *addr, HardwareAddressToStringFlags flags, char buffer[static HW_ADDR_TO_STRING_MAX]) { diff --git a/src/libnm-systemd-shared/src/basic/ether-addr-util.h b/src/libnm-systemd-shared/src/basic/ether-addr-util.h index 187e4ef5..8ebf9c03 100644 --- a/src/libnm-systemd-shared/src/basic/ether-addr-util.h +++ b/src/libnm-systemd-shared/src/basic/ether-addr-util.h @@ -36,11 +36,11 @@ typedef enum HardwareAddressToStringFlags { } HardwareAddressToStringFlags; #define HW_ADDR_TO_STRING_MAX (3*HW_ADDR_MAX_SIZE) -char *hw_addr_to_string_full( +char* hw_addr_to_string_full( const struct hw_addr_data *addr, HardwareAddressToStringFlags flags, char buffer[static HW_ADDR_TO_STRING_MAX]); -static inline char *hw_addr_to_string(const struct hw_addr_data *addr, char buffer[static HW_ADDR_TO_STRING_MAX]) { +static inline char* hw_addr_to_string(const struct hw_addr_data *addr, char buffer[static HW_ADDR_TO_STRING_MAX]) { return hw_addr_to_string_full(addr, 0, buffer); } diff --git a/src/libnm-systemd-shared/src/basic/fd-util.c b/src/libnm-systemd-shared/src/basic/fd-util.c index 584d02f0..e052a6a2 100644 --- a/src/libnm-systemd-shared/src/basic/fd-util.c +++ b/src/libnm-systemd-shared/src/basic/fd-util.c @@ -169,7 +169,10 @@ int fd_nonblock(int fd, bool nonblock) { if (nflags == flags) return 0; - return RET_NERRNO(fcntl(fd, F_SETFL, nflags)); + if (fcntl(fd, F_SETFL, nflags) < 0) + return -errno; + + return 1; } int stdio_disable_nonblock(void) { @@ -212,9 +215,6 @@ int fd_cloexec_many(const int fds[], size_t n_fds, bool cloexec) { continue; RET_GATHER(r, fd_cloexec(*fd, cloexec)); - - if (r >= 0) - r = 1; /* report if we did anything */ } return r; @@ -514,6 +514,16 @@ int pack_fds(int fds[], size_t n_fds) { return 0; } +int fd_validate(int fd) { + if (fd < 0) + return -EBADF; + + if (fcntl(fd, F_GETFD) < 0) + return -errno; + + return 0; +} + int same_fd(int a, int b) { struct stat sta, stb; pid_t pid; @@ -523,25 +533,57 @@ int same_fd(int a, int b) { assert(b >= 0); /* Compares two file descriptors. Note that semantics are quite different depending on whether we - * have kcmp() or we don't. If we have kcmp() this will only return true for dup()ed file - * descriptors, but not otherwise. If we don't have kcmp() this will also return true for two fds of - * the same file, created by separate open() calls. Since we use this call mostly for filtering out - * duplicates in the fd store this difference hopefully doesn't matter too much. */ + * have F_DUPFD_QUERY/kcmp() or we don't. If we have F_DUPFD_QUERY/kcmp() this will only return true + * for dup()ed file descriptors, but not otherwise. If we don't have F_DUPFD_QUERY/kcmp() this will + * also return true for two fds of the same file, created by separate open() calls. Since we use this + * call mostly for filtering out duplicates in the fd store this difference hopefully doesn't matter + * too much. + * + * Guarantees that if either of the passed fds is not allocated we'll return -EBADF. */ + + if (a == b) { + /* Let's validate that the fd is valid */ + r = fd_validate(a); + if (r < 0) + return r; - if (a == b) return true; + } + + /* Try to use F_DUPFD_QUERY if we have it first, as it is the nicest API */ + r = fcntl(a, F_DUPFD_QUERY, b); + if (r > 0) + return true; + if (r == 0) { + /* The kernel will return 0 in case the first fd is allocated, but the 2nd is not. (Which is different in the kcmp() case) Explicitly validate it hence. */ + r = fd_validate(b); + if (r < 0) + return r; + + return false; + } + /* On old kernels (< 6.10) that do not support F_DUPFD_QUERY this will return EINVAL for regular fds, and EBADF on O_PATH fds. Confusing. */ + if (errno == EBADF) { + /* EBADF could mean two things: the first fd is not valid, or it is valid and is O_PATH and + * F_DUPFD_QUERY is not supported. Let's validate the fd explicitly, to distinguish this + * case. */ + r = fd_validate(a); + if (r < 0) + return r; + + /* If the fd is valid, but we got EBADF, then let's try kcmp(). */ + } else if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno) && errno != EINVAL) + return -errno; /* Try to use kcmp() if we have it. */ pid = getpid_cached(); r = kcmp(pid, pid, KCMP_FILE, a, b); - if (r == 0) - return true; - if (r > 0) - return false; + if (r >= 0) + return !r; if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno)) return -errno; - /* We don't have kcmp(), use fstat() instead. */ + /* We have neither F_DUPFD_QUERY nor kcmp(), use fstat() instead. */ if (fstat(a, &sta) < 0) return -errno; @@ -572,14 +614,21 @@ int same_fd(int a, int b) { #endif /* NM_IGNORED */ void cmsg_close_all(struct msghdr *mh) { - struct cmsghdr *cmsg; - assert(mh); - CMSG_FOREACH(cmsg, mh) - if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) + struct cmsghdr *cmsg; + CMSG_FOREACH(cmsg, mh) { + if (cmsg->cmsg_level != SOL_SOCKET) + continue; + + if (cmsg->cmsg_type == SCM_RIGHTS) close_many(CMSG_TYPED_DATA(cmsg, int), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int)); + else if (cmsg->cmsg_type == SCM_PIDFD) { + assert(cmsg->cmsg_len == CMSG_LEN(sizeof(int))); + safe_close(*CMSG_TYPED_DATA(cmsg, int)); + } + } } bool fdname_is_valid(const char *s) { @@ -609,7 +658,6 @@ bool fdname_is_valid(const char *s) { return p - s <= FDNAME_MAX; } -#if 0 /* NM_IGNORED */ int fd_get_path(int fd, char **ret) { int r; @@ -619,19 +667,12 @@ int fd_get_path(int fd, char **ret) { return safe_getcwd(ret); r = readlink_malloc(FORMAT_PROC_FD_PATH(fd), ret); - if (r == -ENOENT) { - /* ENOENT can mean two things: that the fd does not exist or that /proc is not mounted. Let's make - * things debuggable and distinguish the two. */ - - if (proc_mounted() == 0) - return -ENOSYS; /* /proc is not available or not set up properly, we're most likely in some chroot - * environment. */ - return -EBADF; /* The directory exists, hence it's the fd that doesn't. */ - } - + if (r == -ENOENT) + return proc_fd_enoent_errno(); return r; } +#if 0 /* NM_IGNORED */ int move_fd(int from, int to, int cloexec) { int r; @@ -768,8 +809,7 @@ int rearrange_stdio(int original_input_fd, int original_output_fd, int original_ } /* Let's assemble fd[] with the fds to install in place of stdin/stdout/stderr */ - for (int i = 0; i < 3; i++) { - + for (int i = 0; i < 3; i++) if (fd[i] < 0) fd[i] = null_fd; /* A negative parameter means: connect this one to /dev/null */ else if (fd[i] != i && fd[i] < 3) { @@ -782,20 +822,16 @@ int rearrange_stdio(int original_input_fd, int original_output_fd, int original_ fd[i] = copy_fd[i]; } - } /* At this point we now have the fds to use in fd[], and they are all above the stdio range, so that * we have freedom to move them around. If the fds already were at the right places then the specific * fds are -EBADF. Let's now move them to the right places. This is the point of no return. */ - for (int i = 0; i < 3; i++) { - + for (int i = 0; i < 3; i++) if (fd[i] == i) { - /* fd is already in place, but let's make sure O_CLOEXEC is off */ r = fd_cloexec(i, false); if (r < 0) goto finish; - } else { assert(fd[i] > 2); @@ -804,7 +840,6 @@ int rearrange_stdio(int original_input_fd, int original_output_fd, int original_ goto finish; } } - } r = 0; @@ -828,8 +863,6 @@ finish: #endif /* NM_IGNORED */ int fd_reopen(int fd, int flags) { - int r; - assert(fd >= 0 || fd == AT_FDCWD); assert(!FLAGS_SET(flags, O_CREAT)); @@ -865,13 +898,47 @@ int fd_reopen(int fd, int flags) { if (errno != ENOENT) return -errno; - r = proc_mounted(); - if (r == 0) - return -ENOSYS; /* if we have no /proc/, the concept is not implementable */ + return proc_fd_enoent_errno(); + } - return r > 0 ? -EBADF : -ENOENT; /* If /proc/ is definitely around then this means the fd is - * not valid, otherwise let's propagate the original - * error */ + return new_fd; +} + +int fd_reopen_propagate_append_and_position(int fd, int flags) { + /* Invokes fd_reopen(fd, flags), but propagates O_APPEND if set on original fd, and also tries to + * keep current file position. + * + * You should use this if the original fd potentially is O_APPEND, otherwise we get rather + * "unexpected" behavior. Unless you intentionally want to overwrite pre-existing data, and have + * your output overwritten by the next user. + * + * Use case: "systemd-run --pty >> some-log". + * + * The "keep position" part is obviously nonsense for the O_APPEND case, but should reduce surprises + * if someone carefully pre-positioned the passed in original input or non-append output FDs. */ + + assert(fd >= 0); + assert(!(flags & (O_APPEND|O_DIRECTORY))); + + int existing_flags = fcntl(fd, F_GETFL); + if (existing_flags < 0) + return -errno; + + int new_fd = fd_reopen(fd, flags | (existing_flags & O_APPEND)); + if (new_fd < 0) + return new_fd; + + /* Try to adjust the offset, but ignore errors. */ + off_t p = lseek(fd, 0, SEEK_CUR); + if (p > 0) { + off_t new_p = lseek(new_fd, p, SEEK_SET); + if (new_p < 0) + log_debug_errno(errno, + "Failed to propagate file position for re-opened fd %d, ignoring: %m", + fd); + else if (new_p != p) + log_debug("Failed to propagate file position for re-opened fd %d (%lld != %lld), ignoring.", + fd, (long long) new_p, (long long) p); } return new_fd; @@ -922,21 +989,21 @@ int fd_is_opath(int fd) { return FLAGS_SET(r, O_PATH); } -int fd_verify_safe_flags(int fd) { +int fd_verify_safe_flags_full(int fd, int extra_flags) { int flags, unexpected_flags; /* Check if an extrinsic fd is safe to work on (by a privileged service). This ensures that clients * can't trick a privileged service into giving access to a file the client doesn't already have * access to (especially via something like O_PATH). * - * O_NOFOLLOW: For some reason the kernel will return this flag from fcntl; it doesn't go away + * O_NOFOLLOW: For some reason the kernel will return this flag from fcntl(); it doesn't go away * immediately after open(). It should have no effect whatsoever to an already-opened FD, * and since we refuse O_PATH it should be safe. * * RAW_O_LARGEFILE: glibc secretly sets this and neglects to hide it from us if we call fcntl. * See comment in missing_fcntl.h for more details about this. * - * O_DIRECTORY: this is set for directories, which are totally fine + * If 'extra_flags' is specified as non-zero the included flags are also allowed. */ assert(fd >= 0); @@ -945,13 +1012,13 @@ int fd_verify_safe_flags(int fd) { if (flags < 0) return -errno; - unexpected_flags = flags & ~(O_ACCMODE|O_NOFOLLOW|RAW_O_LARGEFILE|O_DIRECTORY); + unexpected_flags = flags & ~(O_ACCMODE|O_NOFOLLOW|RAW_O_LARGEFILE|extra_flags); if (unexpected_flags != 0) return log_debug_errno(SYNTHETIC_ERRNO(EREMOTEIO), "Unexpected flags set for extrinsic fd: 0%o", (unsigned) unexpected_flags); - return 0; + return flags & (O_ACCMODE | extra_flags); /* return the flags variable, but remove the noise */ } int read_nr_open(void) { @@ -1055,8 +1122,6 @@ int fds_are_same_mount(int fd1, int fd2) { int mntid; r = path_get_mnt_id_at_fallback(fd1, "", &mntid); - if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) - return true; /* skip the mount ID check */ if (r < 0) return r; assert(mntid >= 0); @@ -1069,8 +1134,6 @@ int fds_are_same_mount(int fd1, int fd2) { int mntid; r = path_get_mnt_id_at_fallback(fd2, "", &mntid); - if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) - return true; /* skip the mount ID check */ if (r < 0) return r; assert(mntid >= 0); @@ -1082,7 +1145,7 @@ int fds_are_same_mount(int fd1, int fd2) { return statx_mount_same(&st1.nsx, &st2.nsx); } -const char *accmode_to_string(int flags) { +const char* accmode_to_string(int flags) { switch (flags & O_ACCMODE) { case O_RDONLY: return "ro"; @@ -1095,7 +1158,7 @@ const char *accmode_to_string(int flags) { } } -char *format_proc_pid_fd_path(char buf[static PROC_PID_FD_PATH_MAX], pid_t pid, int fd) { +char* format_proc_pid_fd_path(char buf[static PROC_PID_FD_PATH_MAX], pid_t pid, int fd) { assert(buf); assert(fd >= 0); assert(pid >= 0); @@ -1103,3 +1166,20 @@ char *format_proc_pid_fd_path(char buf[static PROC_PID_FD_PATH_MAX], pid_t pid, return buf; } #endif /* NM_IGNORED */ + +int proc_fd_enoent_errno(void) { + int r; + + /* When ENOENT is returned during the use of FORMAT_PROC_FD_PATH, it can mean two things: + * that the fd does not exist or that /proc/ is not mounted. + * Let's make things debuggable and figure out the most appropriate errno. */ + + r = proc_mounted(); + if (r == 0) + return -ENOSYS; /* /proc/ is not available or not set up properly, we're most likely + in some chroot environment. */ + if (r > 0) + return -EBADF; /* If /proc/ is definitely around then this means the fd is not valid. */ + + return -ENOENT; /* Otherwise let's propagate the original ENOENT. */ +} diff --git a/src/libnm-systemd-shared/src/basic/fd-util.h b/src/libnm-systemd-shared/src/basic/fd-util.h index f5498310..93b254c6 100644 --- a/src/libnm-systemd-shared/src/basic/fd-util.h +++ b/src/libnm-systemd-shared/src/basic/fd-util.h @@ -80,6 +80,7 @@ int close_all_fds_without_malloc(const int except[], size_t n_except); int pack_fds(int fds[], size_t n); +int fd_validate(int fd); int same_fd(int a, int b); void cmsg_close_all(struct msghdr *mh); @@ -111,10 +112,15 @@ static inline int make_null_stdio(void) { }) int fd_reopen(int fd, int flags); +int fd_reopen_propagate_append_and_position(int fd, int flags); int fd_reopen_condition(int fd, int flags, int mask, int *ret_new_fd); int fd_is_opath(int fd); -int fd_verify_safe_flags(int fd); + +int fd_verify_safe_flags_full(int fd, int extra_flags); +static inline int fd_verify_safe_flags(int fd) { + return fd_verify_safe_flags_full(fd, 0); +} int read_nr_open(void); int fd_get_diskseq(int fd, uint64_t *ret); @@ -136,7 +142,7 @@ int fds_are_same_mount(int fd1, int fd2); #define PROC_FD_PATH_MAX \ (STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)) -static inline char *format_proc_fd_path(char buf[static PROC_FD_PATH_MAX], int fd) { +static inline char* format_proc_fd_path(char buf[static PROC_FD_PATH_MAX], int fd) { assert(buf); assert(fd >= 0); assert_se(snprintf_ok(buf, PROC_FD_PATH_MAX, "/proc/self/fd/%i", fd)); @@ -150,13 +156,15 @@ static inline char *format_proc_fd_path(char buf[static PROC_FD_PATH_MAX], int f #define PROC_PID_FD_PATH_MAX \ (STRLEN("/proc//fd/") + DECIMAL_STR_MAX(pid_t) + DECIMAL_STR_MAX(int)) -char *format_proc_pid_fd_path(char buf[static PROC_PID_FD_PATH_MAX], pid_t pid, int fd); +char* format_proc_pid_fd_path(char buf[static PROC_PID_FD_PATH_MAX], pid_t pid, int fd); /* Kinda the same as FORMAT_PROC_FD_PATH(), but goes by PID rather than "self" symlink */ #define FORMAT_PROC_PID_FD_PATH(pid, fd) \ format_proc_pid_fd_path((char[PROC_PID_FD_PATH_MAX]) {}, (pid), (fd)) -const char *accmode_to_string(int flags); +int proc_fd_enoent_errno(void); + +const char* accmode_to_string(int flags); /* Like ASSERT_PTR, but for fds */ #define ASSERT_FD(fd) \ diff --git a/src/libnm-systemd-shared/src/basic/fileio.c b/src/libnm-systemd-shared/src/basic/fileio.c index 7ab29816..78231228 100644 --- a/src/libnm-systemd-shared/src/basic/fileio.c +++ b/src/libnm-systemd-shared/src/basic/fileio.c @@ -16,10 +16,12 @@ #include "alloc-util.h" #include "chase.h" +#include "extract-word.h" #include "fd-util.h" #include "fileio.h" #include "fs-util.h" #include "hexdecoct.h" +#include "label.h" #include "log.h" #include "macro.h" #include "mkdir.h" @@ -34,7 +36,7 @@ #include "tmpfile-util.h" /* The maximum size of the file we'll read in one go in read_full_file() (64M). */ -#define READ_FULL_BYTES_MAX (64U*1024U*1024U - 1U) +#define READ_FULL_BYTES_MAX (64U * U64_MB - UINT64_C(1)) /* Used when a size is specified for read_full_file() with READ_FULL_FILE_UNBASE64 or _UNHEX */ #define READ_FULL_FILE_ENCODED_STRING_AMPLIFICATION_BOUNDARY 3 @@ -47,7 +49,7 @@ * exponentially in a loop. We use a size limit of 4M-2 because 4M-1 is the maximum buffer that /proc/sys/ * allows us to read() (larger reads will fail with ENOMEM), and we want to read one extra byte so that we * can detect EOFs. */ -#define READ_VIRTUAL_BYTES_MAX (4U*1024U*1024U - 2U) +#define READ_VIRTUAL_BYTES_MAX (4U * U64_MB - UINT64_C(2)) int fdopen_unlocked(int fd, const char *options, FILE **ret) { assert(ret); @@ -121,7 +123,7 @@ FILE* fmemopen_unlocked(void *buf, size_t size, const char *mode) { } #if 0 /* NM_IGNORED */ -int write_string_stream_ts( +int write_string_stream_full( FILE *f, const char *line, WriteStringFileFlags flags, @@ -233,22 +235,40 @@ static int write_string_file_atomic_at( /* Note that we'd really like to use O_TMPFILE here, but can't really, since we want replacement * semantics here, and O_TMPFILE can't offer that. i.e. rename() replaces but linkat() doesn't. */ + mode_t mode = write_string_file_flags_to_mode(flags); + + bool call_label_ops_post = false; + if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL)) { + r = label_ops_pre(dir_fd, fn, mode); + if (r < 0) + return r; + + call_label_ops_post = true; + } + r = fopen_temporary_at(dir_fd, fn, &f, &p); if (r < 0) - return r; + goto fail; + + if (call_label_ops_post) { + call_label_ops_post = false; - r = write_string_stream_ts(f, line, flags, ts); + r = label_ops_post(fileno(f), /* path= */ NULL, /* created= */ true); + if (r < 0) + goto fail; + } + + r = write_string_stream_full(f, line, flags, ts); if (r < 0) goto fail; - r = fchmod_umask(fileno(f), write_string_file_flags_to_mode(flags)); + r = fchmod_umask(fileno(f), mode); if (r < 0) goto fail; - if (renameat(dir_fd, p, dir_fd, fn) < 0) { - r = -errno; + r = RET_NERRNO(renameat(dir_fd, p, dir_fd, fn)); + if (r < 0) goto fail; - } if (FLAGS_SET(flags, WRITE_STRING_FILE_SYNC)) { /* Sync the rename, too */ @@ -260,20 +280,26 @@ static int write_string_file_atomic_at( return 0; fail: - (void) unlinkat(dir_fd, p, 0); + if (call_label_ops_post) + (void) label_ops_post(f ? fileno(f) : dir_fd, f ? NULL : fn, /* created= */ !!f); + + if (f) + (void) unlinkat(dir_fd, p, 0); return r; } -int write_string_file_ts_at( +int write_string_file_full( int dir_fd, const char *fn, const char *line, WriteStringFileFlags flags, - const struct timespec *ts) { + const struct timespec *ts, + const char *label_fn) { + bool call_label_ops_post = false, made_file = false; _cleanup_fclose_ FILE *f = NULL; _cleanup_close_ int fd = -EBADF; - int q, r; + int r; assert(fn); assert(line); @@ -295,21 +321,40 @@ int write_string_file_ts_at( goto fail; return r; - } else - assert(!ts); + } + + mode_t mode = write_string_file_flags_to_mode(flags); + + if (FLAGS_SET(flags, WRITE_STRING_FILE_LABEL|WRITE_STRING_FILE_CREATE)) { + r = label_ops_pre(dir_fd, label_fn ?: fn, mode); + if (r < 0) + goto fail; + + call_label_ops_post = true; + } /* We manually build our own version of fopen(..., "we") that works without O_CREAT and with O_NOFOLLOW if needed. */ - fd = openat(dir_fd, fn, O_CLOEXEC|O_NOCTTY | - (FLAGS_SET(flags, WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0) | - (FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0) | - (FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0) | - (FLAGS_SET(flags, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) ? O_RDWR : O_WRONLY), - write_string_file_flags_to_mode(flags)); + fd = openat_report_new( + dir_fd, fn, O_CLOEXEC | O_NOCTTY | + (FLAGS_SET(flags, WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0) | + (FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0) | + (FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0) | + (FLAGS_SET(flags, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL) ? O_RDWR : O_WRONLY), + mode, + &made_file); if (fd < 0) { - r = -errno; + r = fd; goto fail; } + if (call_label_ops_post) { + call_label_ops_post = false; + + r = label_ops_post(fd, /* path= */ NULL, made_file); + if (r < 0) + goto fail; + } + r = take_fdopen_unlocked(&fd, "w", &f); if (r < 0) goto fail; @@ -317,26 +362,31 @@ int write_string_file_ts_at( if (flags & WRITE_STRING_FILE_DISABLE_BUFFER) setvbuf(f, NULL, _IONBF, 0); - r = write_string_stream_ts(f, line, flags, ts); + r = write_string_stream_full(f, line, flags, ts); if (r < 0) goto fail; return 0; fail: + if (call_label_ops_post) + (void) label_ops_post(fd >= 0 ? fd : dir_fd, fd >= 0 ? NULL : fn, made_file); + + if (made_file) + (void) unlinkat(dir_fd, fn, 0); + if (!(flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE)) return r; f = safe_fclose(f); + fd = safe_close(fd); - /* OK, the operation failed, but let's see if the right - * contents in place already. If so, eat up the error. */ - - q = verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) || (flags & WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE)); - if (q <= 0) - return r; + /* OK, the operation failed, but let's see if the right contents in place already. If so, eat up the + * error. */ + if (verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) || (flags & WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE)) > 0) + return 0; - return 0; + return r; } int write_string_filef( @@ -358,6 +408,22 @@ int write_string_filef( return write_string_file(fn, p, flags); } +int write_base64_file_at( + int dir_fd, + const char *fn, + const struct iovec *data, + WriteStringFileFlags flags) { + + _cleanup_free_ char *encoded = NULL; + ssize_t n; + + n = base64mem_full(data ? data->iov_base : NULL, data ? data->iov_len : 0, 79, &encoded); + if (n < 0) + return n; + + return write_string_file_at(dir_fd, fn, encoded, flags); +} + int read_one_line_file_at(int dir_fd, const char *filename, char **ret) { _cleanup_fclose_ FILE *f = NULL; int r; @@ -796,35 +862,49 @@ int read_full_file_full( } #if 0 /* NM_IGNORED */ -int executable_is_script(const char *path, char **interpreter) { - _cleanup_free_ char *line = NULL; - size_t len; - char *ans; +int script_get_shebang_interpreter(const char *path, char **ret) { + _cleanup_fclose_ FILE *f = NULL; int r; assert(path); - r = read_one_line_file(path, &line); - if (r == -ENOBUFS) /* First line overly long? if so, then it's not a script */ - return 0; + f = fopen(path, "re"); + if (!f) + return -errno; + + char c; + r = safe_fgetc(f, &c); if (r < 0) return r; + if (r == 0) + return -EBADMSG; + if (c != '#') + return -EMEDIUMTYPE; + r = safe_fgetc(f, &c); + if (r < 0) + return r; + if (r == 0) + return -EBADMSG; + if (c != '!') + return -EMEDIUMTYPE; - if (!startswith(line, "#!")) - return 0; - - ans = strstrip(line + 2); - len = strcspn(ans, " \t"); + _cleanup_free_ char *line = NULL; + r = read_line(f, LONG_LINE_MAX, &line); + if (r < 0) + return r; - if (len == 0) - return 0; + _cleanup_free_ char *p = NULL; + const char *s = line; - ans = strndup(ans, len); - if (!ans) - return -ENOMEM; + r = extract_first_word(&s, &p, /* separators = */ NULL, /* flags = */ 0); + if (r < 0) + return r; + if (r == 0) + return -ENOEXEC; - *interpreter = ans; - return 1; + if (ret) + *ret = TAKE_PTR(p); + return 0; } /** @@ -897,19 +977,21 @@ int get_proc_field(const char *filename, const char *pattern, const char *termin return 0; } -DIR *xopendirat(int fd, const char *name, int flags) { - _cleanup_close_ int nfd = -EBADF; +DIR* xopendirat(int dir_fd, const char *name, int flags) { + _cleanup_close_ int fd = -EBADF; - assert(!(flags & O_CREAT)); + assert(dir_fd >= 0 || dir_fd == AT_FDCWD); + assert(name); + assert(!(flags & (O_CREAT|O_TMPFILE))); - if (fd == AT_FDCWD && flags == 0) + if (dir_fd == AT_FDCWD && flags == 0) return opendir(name); - nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0); - if (nfd < 0) + fd = openat(dir_fd, name, O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags); + if (fd < 0) return NULL; - return take_fdopendir(&nfd); + return take_fdopendir(&fd); } #endif /* NM_IGNORED */ @@ -1364,6 +1446,29 @@ int fputs_with_separator(FILE *f, const char *s, const char *separator, bool *sp return 0; } +int fputs_with_newline(FILE *f, const char *s) { + + /* This is like fputs() but outputs a trailing newline char, but only if the string isn't empty + * and doesn't end in a newline already. Returns 0 in case we didn't append a newline, > 0 otherwise. */ + + if (isempty(s)) + return 0; + + if (!f) + f = stdout; + + if (fputs(s, f) < 0) + return -EIO; + + if (endswith(s, "\n")) + return 0; + + if (fputc('\n', f) < 0) + return -EIO; + + return 1; +} + #if 0 /* NM_IGNORED */ /* A bitmask of the EOL markers we know */ typedef enum EndOfLineMarker { @@ -1515,7 +1620,7 @@ int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) { int read_stripped_line(FILE *f, size_t limit, char **ret) { _cleanup_free_ char *s = NULL; - int r; + int r, k; assert(f); @@ -1524,23 +1629,17 @@ int read_stripped_line(FILE *f, size_t limit, char **ret) { return r; if (ret) { - const char *p; - - p = strstrip(s); + const char *p = strstrip(s); if (p == s) *ret = TAKE_PTR(s); else { - char *copy; - - copy = strdup(p); - if (!copy) - return -ENOMEM; - - *ret = copy; + k = strdup_to(ret, p); + if (k < 0) + return k; } } - return r; + return r > 0; /* Return 1 if something was read. */ } int safe_fgetc(FILE *f, char *ret) { diff --git a/src/libnm-systemd-shared/src/basic/fileio.h b/src/libnm-systemd-shared/src/basic/fileio.h index 03c3f3ff..bd053050 100644 --- a/src/libnm-systemd-shared/src/basic/fileio.h +++ b/src/libnm-systemd-shared/src/basic/fileio.h @@ -28,11 +28,7 @@ typedef enum { WRITE_STRING_FILE_MODE_0600 = 1 << 10, WRITE_STRING_FILE_MODE_0444 = 1 << 11, WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL = 1 << 12, - - /* And before you wonder, why write_string_file_atomic_label_ts() is a separate function instead of just one - more flag here: it's about linking: we don't want to pull -lselinux into all users of write_string_file() - and friends. */ - + WRITE_STRING_FILE_LABEL = 1 << 13, } WriteStringFileFlags; typedef enum { @@ -51,23 +47,22 @@ DIR* take_fdopendir(int *dfd); FILE* open_memstream_unlocked(char **ptr, size_t *sizeloc); FILE* fmemopen_unlocked(void *buf, size_t size, const char *mode); -int write_string_stream_ts(FILE *f, const char *line, WriteStringFileFlags flags, const struct timespec *ts); +int write_string_stream_full(FILE *f, const char *line, WriteStringFileFlags flags, const struct timespec *ts); static inline int write_string_stream(FILE *f, const char *line, WriteStringFileFlags flags) { - return write_string_stream_ts(f, line, flags, NULL); -} -int write_string_file_ts_at(int dir_fd, const char *fn, const char *line, WriteStringFileFlags flags, const struct timespec *ts); -static inline int write_string_file_ts(const char *fn, const char *line, WriteStringFileFlags flags, const struct timespec *ts) { - return write_string_file_ts_at(AT_FDCWD, fn, line, flags, ts); + return write_string_stream_full(f, line, flags, NULL); } + +int write_string_file_full(int dir_fd, const char *fn, const char *line, WriteStringFileFlags flags, const struct timespec *ts, const char *label_fn); static inline int write_string_file_at(int dir_fd, const char *fn, const char *line, WriteStringFileFlags flags) { - return write_string_file_ts_at(dir_fd, fn, line, flags, NULL); + return write_string_file_full(dir_fd, fn, line, flags, NULL, NULL); } static inline int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) { - return write_string_file_ts(fn, line, flags, NULL); + return write_string_file_at(AT_FDCWD, fn, line, flags); } - int write_string_filef(const char *fn, WriteStringFileFlags flags, const char *format, ...) _printf_(3, 4); +int write_base64_file_at(int dir_fd, const char *fn, const struct iovec *data, WriteStringFileFlags flags); + int read_one_line_file_at(int dir_fd, const char *filename, char **ret); static inline int read_one_line_file(const char *filename, char **ret) { return read_one_line_file_at(AT_FDCWD, filename, ret); @@ -99,11 +94,11 @@ static inline int verify_file(const char *fn, const char *blob, bool accept_extr return verify_file_at(AT_FDCWD, fn, blob, accept_extra_nl); } -int executable_is_script(const char *path, char **interpreter); +int script_get_shebang_interpreter(const char *path, char **ret); int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field); -DIR *xopendirat(int dirfd, const char *name, int flags); +DIR* xopendirat(int dir_fd, const char *name, int flags); typedef enum XfopenFlags { XFOPEN_UNLOCKED = 1 << 0, /* call __fsetlocking(FSETLOCKING_BYCALLER) after opened */ @@ -144,6 +139,7 @@ int write_timestamp_file_atomic(const char *fn, usec_t n); int read_timestamp_file(const char *fn, usec_t *ret); int fputs_with_separator(FILE *f, const char *s, const char *separator, bool *space); +int fputs_with_newline(FILE *f, const char *s); typedef enum ReadLineFlags { READ_LINE_ONLY_NUL = 1 << 0, @@ -152,23 +148,21 @@ typedef enum ReadLineFlags { } ReadLineFlags; int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret); - -static inline bool file_offset_beyond_memory_size(off_t x) { - if (x < 0) /* off_t is signed, filter that out */ - return false; - return (uint64_t) x > (uint64_t) SIZE_MAX; -} - static inline int read_line(FILE *f, size_t limit, char **ret) { return read_line_full(f, limit, 0, ret); } - static inline int read_nul_string(FILE *f, size_t limit, char **ret) { return read_line_full(f, limit, READ_LINE_ONLY_NUL, ret); } int read_stripped_line(FILE *f, size_t limit, char **ret); +static inline bool file_offset_beyond_memory_size(off_t x) { + if (x < 0) /* off_t is signed, filter that out */ + return false; + return (uint64_t) x > (uint64_t) SIZE_MAX; +} + int safe_fgetc(FILE *f, char *ret); int warn_file_is_world_accessible(const char *filename, struct stat *st, const char *unit, unsigned line); diff --git a/src/libnm-systemd-shared/src/basic/format-ifname.c b/src/libnm-systemd-shared/src/basic/format-ifname.c new file mode 100644 index 00000000..81592998 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/format-ifname.c @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include "format-ifname.h" +#include "string-util.h" + +assert_cc(STRLEN("%") + DECIMAL_STR_MAX(int) <= IF_NAMESIZE); + +int format_ifname_full(int ifindex, FormatIfnameFlag flag, char buf[static IF_NAMESIZE]) { + if (ifindex <= 0) + return -EINVAL; + + if (if_indextoname(ifindex, buf)) + return 0; + + if (!FLAGS_SET(flag, FORMAT_IFNAME_IFINDEX)) + return -errno; + + if (FLAGS_SET(flag, FORMAT_IFNAME_IFINDEX_WITH_PERCENT)) + assert_se(snprintf_ok(buf, IF_NAMESIZE, "%%%d", ifindex)); + else + assert_se(snprintf_ok(buf, IF_NAMESIZE, "%d", ifindex)); + + return 0; +} + +int format_ifname_full_alloc(int ifindex, FormatIfnameFlag flag, char **ret) { + char buf[IF_NAMESIZE]; + int r; + + assert(ret); + + r = format_ifname_full(ifindex, flag, buf); + if (r < 0) + return r; + + return strdup_to(ret, buf); +} diff --git a/src/libnm-systemd-shared/src/basic/format-ifname.h b/src/libnm-systemd-shared/src/basic/format-ifname.h new file mode 100644 index 00000000..84415b13 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/format-ifname.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include <net/if.h> + +typedef enum { + FORMAT_IFNAME_IFINDEX = 1 << 0, + FORMAT_IFNAME_IFINDEX_WITH_PERCENT = (1 << 1) | FORMAT_IFNAME_IFINDEX, +} FormatIfnameFlag; + +int format_ifname_full(int ifindex, FormatIfnameFlag flag, char buf[static IF_NAMESIZE]); +int format_ifname_full_alloc(int ifindex, FormatIfnameFlag flag, char **ret); + +static inline int format_ifname(int ifindex, char buf[static IF_NAMESIZE]) { + return format_ifname_full(ifindex, 0, buf); +} +static inline int format_ifname_alloc(int ifindex, char **ret) { + return format_ifname_full_alloc(ifindex, 0, ret); +} + +static inline char* _format_ifname_full(int ifindex, FormatIfnameFlag flag, char buf[static IF_NAMESIZE]) { + (void) format_ifname_full(ifindex, flag, buf); + return buf; +} + +#define FORMAT_IFNAME_FULL(index, flag) _format_ifname_full(index, flag, (char[IF_NAMESIZE]){}) +#define FORMAT_IFNAME(index) _format_ifname_full(index, 0, (char[IF_NAMESIZE]){}) diff --git a/src/libnm-systemd-shared/src/basic/format-util.c b/src/libnm-systemd-shared/src/basic/format-util.c index ebe52713..b2a5d2d0 100644 --- a/src/libnm-systemd-shared/src/basic/format-util.c +++ b/src/libnm-systemd-shared/src/basic/format-util.c @@ -7,44 +7,7 @@ #include "stdio-util.h" #include "strxcpyx.h" -assert_cc(STRLEN("%") + DECIMAL_STR_MAX(int) <= IF_NAMESIZE); -int format_ifname_full(int ifindex, FormatIfnameFlag flag, char buf[static IF_NAMESIZE]) { - if (ifindex <= 0) - return -EINVAL; - - if (if_indextoname(ifindex, buf)) - return 0; - - if (!FLAGS_SET(flag, FORMAT_IFNAME_IFINDEX)) - return -errno; - - if (FLAGS_SET(flag, FORMAT_IFNAME_IFINDEX_WITH_PERCENT)) - assert(snprintf_ok(buf, IF_NAMESIZE, "%%%d", ifindex)); - else - assert(snprintf_ok(buf, IF_NAMESIZE, "%d", ifindex)); - - return 0; -} - -int format_ifname_full_alloc(int ifindex, FormatIfnameFlag flag, char **ret) { - char buf[IF_NAMESIZE], *copy; - int r; - - assert(ret); - - r = format_ifname_full(ifindex, flag, buf); - if (r < 0) - return r; - - copy = strdup(buf); - if (!copy) - return -ENOMEM; - - *ret = copy; - return 0; -} - -char *format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag) { +char* format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag) { typedef struct { const char *suffix; uint64_t factor; @@ -77,15 +40,17 @@ char *format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag) { for (size_t i = 0; i < n; i++) if (t >= table[i].factor) { - if (flag & FORMAT_BYTES_BELOW_POINT) { + uint64_t remainder = i != n - 1 ? + (t / table[i + 1].factor * 10 / table[n - 1].factor) % 10 : + (t * 10 / table[i].factor) % 10; + + if (FLAGS_SET(flag, FORMAT_BYTES_BELOW_POINT) && remainder > 0) (void) snprintf(buf, l, "%" PRIu64 ".%" PRIu64 "%s", t / table[i].factor, - i != n - 1 ? - (t / table[i + 1].factor * UINT64_C(10) / table[n - 1].factor) % UINT64_C(10): - (t * UINT64_C(10) / table[i].factor) % UINT64_C(10), + remainder, table[i].suffix); - } else + else (void) snprintf(buf, l, "%" PRIu64 "%s", t / table[i].factor, diff --git a/src/libnm-systemd-shared/src/basic/format-util.h b/src/libnm-systemd-shared/src/basic/format-util.h index 8a80eb33..1939ee18 100644 --- a/src/libnm-systemd-shared/src/basic/format-util.h +++ b/src/libnm-systemd-shared/src/basic/format-util.h @@ -2,7 +2,6 @@ #pragma once #include <inttypes.h> -#include <net/if.h> #include <stdbool.h> #include "cgroup-util.h" @@ -69,29 +68,6 @@ assert_cc(sizeof(gid_t) == sizeof(uint32_t)); #endif typedef enum { - FORMAT_IFNAME_IFINDEX = 1 << 0, - FORMAT_IFNAME_IFINDEX_WITH_PERCENT = (1 << 1) | FORMAT_IFNAME_IFINDEX, -} FormatIfnameFlag; - -int format_ifname_full(int ifindex, FormatIfnameFlag flag, char buf[static IF_NAMESIZE]); -int format_ifname_full_alloc(int ifindex, FormatIfnameFlag flag, char **ret); - -static inline int format_ifname(int ifindex, char buf[static IF_NAMESIZE]) { - return format_ifname_full(ifindex, 0, buf); -} -static inline int format_ifname_alloc(int ifindex, char **ret) { - return format_ifname_full_alloc(ifindex, 0, ret); -} - -static inline char *_format_ifname_full(int ifindex, FormatIfnameFlag flag, char buf[static IF_NAMESIZE]) { - (void) format_ifname_full(ifindex, flag, buf); - return buf; -} - -#define FORMAT_IFNAME_FULL(index, flag) _format_ifname_full(index, flag, (char[IF_NAMESIZE]){}) -#define FORMAT_IFNAME(index) _format_ifname_full(index, 0, (char[IF_NAMESIZE]){}) - -typedef enum { FORMAT_BYTES_USE_IEC = 1 << 0, FORMAT_BYTES_BELOW_POINT = 1 << 1, FORMAT_BYTES_TRAILING_B = 1 << 2, @@ -99,10 +75,10 @@ typedef enum { #define FORMAT_BYTES_MAX 16U -char *format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag) _warn_unused_result_; +char* format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag) _warn_unused_result_; _warn_unused_result_ -static inline char *format_bytes(char *buf, size_t l, uint64_t t) { +static inline char* format_bytes(char *buf, size_t l, uint64_t t) { return format_bytes_full(buf, l, t, FORMAT_BYTES_USE_IEC | FORMAT_BYTES_BELOW_POINT | FORMAT_BYTES_TRAILING_B); } diff --git a/src/libnm-systemd-shared/src/basic/fs-util.c b/src/libnm-systemd-shared/src/basic/fs-util.c index 3f414794..0202933d 100644 --- a/src/libnm-systemd-shared/src/basic/fs-util.c +++ b/src/libnm-systemd-shared/src/basic/fs-util.c @@ -12,6 +12,7 @@ #include "alloc-util.h" #include "btrfs.h" +#include "chattr-util.h" #include "dirent-util.h" #include "fd-util.h" #include "fileio.h" @@ -156,10 +157,6 @@ int readlinkat_malloc(int fd, const char *p, char **ret) { } } -int readlink_malloc(const char *p, char **ret) { - return readlinkat_malloc(AT_FDCWD, p, ret); -} - int readlink_value(const char *p, char **ret) { _cleanup_free_ char *link = NULL, *name = NULL; int r; @@ -318,10 +315,7 @@ int fchmod_opath(int fd, mode_t m) { if (errno != ENOENT) return -errno; - if (proc_mounted() == 0) - return -ENOSYS; /* if we have no /proc/, the concept is not implementable */ - - return -ENOENT; + return proc_fd_enoent_errno(); } return 0; @@ -330,14 +324,21 @@ int fchmod_opath(int fd, mode_t m) { int futimens_opath(int fd, const struct timespec ts[2]) { /* Similar to fchmod_opath() but for futimens() */ - if (utimensat(AT_FDCWD, FORMAT_PROC_FD_PATH(fd), ts, 0) < 0) { + assert(fd >= 0); + + if (utimensat(fd, "", ts, AT_EMPTY_PATH) >= 0) + return 0; + if (errno != EINVAL) + return -errno; + + /* Support for AT_EMPTY_PATH is added rather late (kernel 5.8), so fall back to going through /proc/ + * if unavailable. */ + + if (utimensat(AT_FDCWD, FORMAT_PROC_FD_PATH(fd), ts, /* flags = */ 0) < 0) { if (errno != ENOENT) return -errno; - if (proc_mounted() == 0) - return -ENOSYS; /* if we have no /proc/, the concept is not implementable */ - - return -ENOENT; + return proc_fd_enoent_errno(); } return 0; @@ -375,9 +376,21 @@ int fd_warn_permissions(const char *path, int fd) { return stat_warn_permissions(path, &st); } +int touch_fd(int fd, usec_t stamp) { + assert(fd >= 0); + + if (stamp == USEC_INFINITY) + return futimens_opath(fd, /* ts= */ NULL); + + struct timespec ts[2]; + timespec_store(ts + 0, stamp); + ts[1] = ts[0]; + return futimens_opath(fd, ts); +} + int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) { _cleanup_close_ int fd = -EBADF; - int r, ret; + int ret; assert(path); @@ -409,21 +422,10 @@ int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gi * something fchown(), fchmod(), futimensat() don't allow. */ ret = fchmod_and_chown(fd, mode, uid, gid); - if (stamp != USEC_INFINITY) { - struct timespec ts[2]; - - timespec_store(&ts[0], stamp); - ts[1] = ts[0]; - r = futimens_opath(fd, ts); - } else - r = futimens_opath(fd, NULL); - if (r < 0 && ret >= 0) - return r; - - return ret; + return RET_GATHER(ret, touch_fd(fd, stamp)); } -int symlink_idempotent(const char *from, const char *to, bool make_relative) { +int symlinkat_idempotent(const char *from, int atfd, const char *to, bool make_relative) { _cleanup_free_ char *relpath = NULL; int r; @@ -438,13 +440,13 @@ int symlink_idempotent(const char *from, const char *to, bool make_relative) { from = relpath; } - if (symlink(from, to) < 0) { + if (symlinkat(from, atfd, to) < 0) { _cleanup_free_ char *p = NULL; if (errno != EEXIST) return -errno; - r = readlink_malloc(to, &p); + r = readlinkat_malloc(atfd, to, &p); if (r == -EINVAL) /* Not a symlink? In that case return the original error we encountered: -EEXIST */ return -EEXIST; if (r < 0) /* Any other error? In that case propagate it as is */ @@ -632,11 +634,11 @@ static int tmp_dir_internal(const char *def, const char **ret) { return 0; } - k = is_dir(def, true); + k = is_dir(def, /* follow = */ true); if (k == 0) k = -ENOTDIR; if (k < 0) - return r < 0 ? r : k; + return RET_GATHER(r, k); *ret = def; return 0; @@ -644,6 +646,7 @@ static int tmp_dir_internal(const char *def, const char **ret) { #if 0 /* NM_IGNORED */ int var_tmp_dir(const char **ret) { + assert(ret); /* Returns the location for "larger" temporary files, that is backed by physical storage if available, and thus * even might survive a boot: /var/tmp. If $TMPDIR (or related environment variables) are set, its value is @@ -655,6 +658,7 @@ int var_tmp_dir(const char **ret) { #endif /* NM_IGNORED */ int tmp_dir(const char **ret) { + assert(ret); /* Similar to var_tmp_dir() above, but returns the location for "smaller" temporary files, which is usually * backed by an in-memory file system: /tmp. */ @@ -664,6 +668,8 @@ int tmp_dir(const char **ret) { #if 0 /* NM_IGNORED */ int unlink_or_warn(const char *filename) { + assert(filename); + if (unlink(filename) < 0 && errno != ENOENT) /* If the file doesn't exist and the fs simply was read-only (in which * case unlink() returns EROFS even if the file doesn't exist), don't @@ -675,39 +681,35 @@ int unlink_or_warn(const char *filename) { } int access_fd(int fd, int mode) { + assert(fd >= 0); + /* Like access() but operates on an already open fd */ + if (faccessat(fd, "", mode, AT_EMPTY_PATH) >= 0) + return 0; + if (errno != EINVAL) + return -errno; + + /* Support for AT_EMPTY_PATH is added rather late (kernel 5.8), so fall back to going through /proc/ + * if unavailable. */ + if (access(FORMAT_PROC_FD_PATH(fd), mode) < 0) { if (errno != ENOENT) return -errno; - /* ENOENT can mean two things: that the fd does not exist or that /proc is not mounted. Let's - * make things debuggable and distinguish the two. */ - - if (proc_mounted() == 0) - return -ENOSYS; /* /proc is not available or not set up properly, we're most likely in some chroot - * environment. */ - - return -EBADF; /* The directory exists, hence it's the fd that doesn't. */ + return proc_fd_enoent_errno(); } return 0; } -void unlink_tempfilep(char (*p)[]) { - /* If the file is created with mkstemp(), it will (almost always) - * change the suffix. Treat this as a sign that the file was - * successfully created. We ignore both the rare case where the - * original suffix is used and unlink failures. */ - if (!endswith(*p, ".XXXXXX")) - (void) unlink(*p); -} - int unlinkat_deallocate(int fd, const char *name, UnlinkDeallocateFlags flags) { _cleanup_close_ int truncate_fd = -EBADF; struct stat st; off_t l, bs; + assert(fd >= 0 || fd == AT_FDCWD); + assert(name); assert((flags & ~(UNLINK_REMOVEDIR|UNLINK_ERASE)) == 0); /* Operates like unlinkat() but also deallocates the file contents if it is a regular file and there's no other @@ -1028,7 +1030,7 @@ int parse_cifs_service( return 0; } -int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode) { +int open_mkdir_at_full(int dirfd, const char *path, int flags, XOpenFlags xopen_flags, mode_t mode) { _cleanup_close_ int fd = -EBADF, parent_fd = -EBADF; _cleanup_free_ char *fname = NULL, *parent = NULL; int r; @@ -1064,7 +1066,7 @@ int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode) { path = fname; } - fd = xopenat_full(dirfd, path, flags|O_CREAT|O_DIRECTORY|O_NOFOLLOW, /* xopen_flags = */ 0, mode); + fd = xopenat_full(dirfd, path, flags|O_CREAT|O_DIRECTORY|O_NOFOLLOW, xopen_flags, mode); if (IN_SET(fd, -ELOOP, -ENOTDIR)) return -EEXIST; if (fd < 0) @@ -1074,46 +1076,50 @@ int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode) { } int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, bool *ret_newly_created) { - unsigned attempts = 7; int fd; /* Just like openat(), but adds one thing: optionally returns whether we created the file anew or if * it already existed before. This is only relevant if O_CREAT is set without O_EXCL, and thus will - * shortcut to openat() otherwise */ - - if (!ret_newly_created) - return RET_NERRNO(openat(dirfd, pathname, flags, mode)); + * shortcut to openat() otherwise. + * + * Note that this routine is a bit more strict with symlinks than regular openat() is. If O_NOFOLLOW + * is not specified, then we'll follow the symlink when opening an existing file but we will *not* + * follow it when creating a new one (because that's a terrible UNIX misfeature and generally a + * security hole). */ if (!FLAGS_SET(flags, O_CREAT) || FLAGS_SET(flags, O_EXCL)) { fd = openat(dirfd, pathname, flags, mode); if (fd < 0) return -errno; - *ret_newly_created = FLAGS_SET(flags, O_CREAT); + if (ret_newly_created) + *ret_newly_created = FLAGS_SET(flags, O_CREAT); return fd; } - for (;;) { + for (unsigned attempts = 7;;) { /* First, attempt to open without O_CREAT/O_EXCL, i.e. open existing file */ fd = openat(dirfd, pathname, flags & ~(O_CREAT | O_EXCL), mode); if (fd >= 0) { - *ret_newly_created = false; + if (ret_newly_created) + *ret_newly_created = false; return fd; } if (errno != ENOENT) return -errno; - /* So the file didn't exist yet, hence create it with O_CREAT/O_EXCL. */ - fd = openat(dirfd, pathname, flags | O_CREAT | O_EXCL, mode); + /* So the file didn't exist yet, hence create it with O_CREAT/O_EXCL/O_NOFOLLOW. */ + fd = openat(dirfd, pathname, flags | O_CREAT | O_EXCL | O_NOFOLLOW, mode); if (fd >= 0) { - *ret_newly_created = true; + if (ret_newly_created) + *ret_newly_created = true; return fd; } if (errno != EEXIST) return -errno; - /* Hmm, so now we got EEXIST? So it apparently exists now? If so, let's try to open again - * without the two flags. But let's not spin forever, hence put a limit on things */ + /* Hmm, so now we got EEXIST? Then someone might have created the file between the first and + * second call to openat(). Let's try again but with a limit so we don't spin forever. */ if (--attempts == 0) /* Give up eventually, somebody is playing with us */ return -EEXIST; @@ -1122,11 +1128,14 @@ int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, b int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode) { _cleanup_close_ int fd = -EBADF; - bool made = false; + bool made_dir = false, made_file = false; int r; assert(dir_fd >= 0 || dir_fd == AT_FDCWD); + /* An inode cannot be both a directory and a regular file at the same time. */ + assert(!(FLAGS_SET(open_flags, O_DIRECTORY) && FLAGS_SET(xopen_flags, XO_REGULAR))); + /* This is like openat(), but has a few tricks up its sleeves, extending behaviour: * * • O_DIRECTORY|O_CREAT is supported, which causes a directory to be created, and immediately @@ -1135,17 +1144,37 @@ int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_ * • If O_CREAT is used with XO_LABEL, any created file will be immediately relabelled. * * • If the path is specified NULL or empty, behaves like fd_reopen(). + * + * • If XO_NOCOW is specified will turn on the NOCOW btrfs flag on the file, if available. + * + * • if XO_REGULAR is specified will return an error if inode is not a regular file. + * + * • If mode is specified as MODE_INVALID, we'll use 0755 for dirs, and 0644 for regular files. */ + if (mode == MODE_INVALID) + mode = (open_flags & O_DIRECTORY) ? 0755 : 0644; + if (isempty(path)) { assert(!FLAGS_SET(open_flags, O_CREAT|O_EXCL)); + + if (FLAGS_SET(xopen_flags, XO_REGULAR)) { + r = fd_verify_regular(dir_fd); + if (r < 0) + return r; + } + return fd_reopen(dir_fd, open_flags & ~O_NOFOLLOW); } + bool call_label_ops_post = false; + if (FLAGS_SET(open_flags, O_CREAT) && FLAGS_SET(xopen_flags, XO_LABEL)) { r = label_ops_pre(dir_fd, path, FLAGS_SET(open_flags, O_DIRECTORY) ? S_IFDIR : S_IFREG); if (r < 0) return r; + + call_label_ops_post = true; } if (FLAGS_SET(open_flags, O_DIRECTORY|O_CREAT)) { @@ -1156,49 +1185,100 @@ int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_ if (r == -EEXIST) { if (FLAGS_SET(open_flags, O_EXCL)) return -EEXIST; - - made = false; } else if (r < 0) return r; else - made = true; - - if (FLAGS_SET(xopen_flags, XO_LABEL)) { - r = label_ops_post(dir_fd, path); - if (r < 0) - return r; - } + made_dir = true; open_flags &= ~(O_EXCL|O_CREAT); - xopen_flags &= ~XO_LABEL; } - fd = RET_NERRNO(openat(dir_fd, path, open_flags, mode)); - if (fd < 0) { - if (IN_SET(fd, - /* We got ENOENT? then someone else immediately removed it after we - * created it. In that case let's return immediately without unlinking - * anything, because there simply isn't anything to unlink anymore. */ - -ENOENT, - /* is a symlink? exists already → created by someone else, don't unlink */ - -ELOOP, - /* not a directory? exists already → created by someone else, don't unlink */ - -ENOTDIR)) - return fd; + if (FLAGS_SET(xopen_flags, XO_REGULAR)) { + /* Guarantee we return a regular fd only, and don't open the file unless we verified it + * first */ - if (made) - (void) unlinkat(dir_fd, path, AT_REMOVEDIR); + if (FLAGS_SET(open_flags, O_PATH)) { + fd = openat(dir_fd, path, open_flags, mode); + if (fd < 0) { + r = -errno; + goto error; + } - return fd; + r = fd_verify_regular(fd); + if (r < 0) + goto error; + + } else if (FLAGS_SET(open_flags, O_CREAT|O_EXCL)) { + /* In O_EXCL mode we can just create the thing, everything is dealt with for us */ + fd = openat(dir_fd, path, open_flags, mode); + if (fd < 0) { + r = -errno; + goto error; + } + + made_file = true; + } else { + /* Otherwise pin the inode first via O_PATH */ + _cleanup_close_ int inode_fd = openat(dir_fd, path, O_PATH|O_CLOEXEC|(open_flags & O_NOFOLLOW)); + if (inode_fd < 0) { + if (errno != ENOENT || !FLAGS_SET(open_flags, O_CREAT)) { + r = -errno; + goto error; + } + + /* Doesn't exist yet, then try to create it */ + fd = openat(dir_fd, path, open_flags|O_CREAT|O_EXCL, mode); + if (fd < 0) { + r = -errno; + goto error; + } + + made_file = true; + } else { + /* OK, we pinned it. Now verify it's actually a regular file, and then reopen it */ + r = fd_verify_regular(inode_fd); + if (r < 0) + goto error; + + fd = fd_reopen(inode_fd, open_flags & ~(O_NOFOLLOW|O_CREAT)); + if (fd < 0) { + r = fd; + goto error; + } + } + } + } else { + fd = openat_report_new(dir_fd, path, open_flags, mode, &made_file); + if (fd < 0) { + r = fd; + goto error; + } } - if (FLAGS_SET(open_flags, O_CREAT) && FLAGS_SET(xopen_flags, XO_LABEL)) { - r = label_ops_post(dir_fd, path); + if (call_label_ops_post) { + call_label_ops_post = false; + + r = label_ops_post(fd, /* path= */ NULL, made_file || made_dir); if (r < 0) - return r; + goto error; + } + + if (FLAGS_SET(xopen_flags, XO_NOCOW)) { + r = chattr_fd(fd, FS_NOCOW_FL, FS_NOCOW_FL, NULL); + if (r < 0 && !ERRNO_IS_NOT_SUPPORTED(r)) + goto error; } return TAKE_FD(fd); + +error: + if (call_label_ops_post) + (void) label_ops_post(fd >= 0 ? fd : dir_fd, fd >= 0 ? NULL : path, made_dir || made_file); + + if (made_dir || made_file) + (void) unlinkat(dir_fd, path, made_dir ? AT_REMOVEDIR : 0); + + return r; } #if 0 /* NM_IGNORED */ @@ -1247,4 +1327,103 @@ int xopenat_lock_full( return TAKE_FD(fd); } + +int link_fd(int fd, int newdirfd, const char *newpath) { + int r, k; + + assert(fd >= 0); + assert(newdirfd >= 0 || newdirfd == AT_FDCWD); + assert(newpath); + + /* Try linking via /proc/self/fd/ first. */ + r = RET_NERRNO(linkat(AT_FDCWD, FORMAT_PROC_FD_PATH(fd), newdirfd, newpath, AT_SYMLINK_FOLLOW)); + if (r != -ENOENT) + return r; + + /* Fall back to symlinking via AT_EMPTY_PATH as fallback (this requires CAP_DAC_READ_SEARCH and a + * more recent kernel, but does not require /proc/ mounted) */ + k = proc_mounted(); + if (k < 0) + return r; + if (k > 0) + return -EBADF; + + return RET_NERRNO(linkat(fd, "", newdirfd, newpath, AT_EMPTY_PATH)); +} + +int linkat_replace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) { + _cleanup_close_ int old_fd = -EBADF; + int r; + + assert(olddirfd >= 0 || olddirfd == AT_FDCWD); + assert(newdirfd >= 0 || newdirfd == AT_FDCWD); + assert(!isempty(newpath)); /* source path is optional, but the target path is not */ + + /* Like linkat() but replaces the target if needed. Is a NOP if source and target already share the + * same inode. */ + + if (olddirfd == AT_FDCWD && isempty(oldpath)) /* Refuse operating on the cwd (which is a dir, and dirs can't be hardlinked) */ + return -EISDIR; + + if (path_implies_directory(oldpath)) /* Refuse these definite directories early */ + return -EISDIR; + + if (path_implies_directory(newpath)) + return -EISDIR; + + /* First, try to link this directly */ + if (oldpath) + r = RET_NERRNO(linkat(olddirfd, oldpath, newdirfd, newpath, 0)); + else + r = link_fd(olddirfd, newdirfd, newpath); + if (r >= 0) + return 0; + if (r != -EEXIST) + return r; + + old_fd = xopenat(olddirfd, oldpath, O_PATH|O_CLOEXEC); + if (old_fd < 0) + return old_fd; + + struct stat old_st; + if (fstat(old_fd, &old_st) < 0) + return -errno; + + if (S_ISDIR(old_st.st_mode)) /* Don't bother if we are operating on a directory */ + return -EISDIR; + + struct stat new_st; + if (fstatat(newdirfd, newpath, &new_st, AT_SYMLINK_NOFOLLOW) < 0) + return -errno; + + if (S_ISDIR(new_st.st_mode)) /* Refuse replacing directories */ + return -EEXIST; + + if (stat_inode_same(&old_st, &new_st)) /* Already the same inode? Then shortcut this */ + return 0; + + _cleanup_free_ char *tmp_path = NULL; + r = tempfn_random(newpath, /* extra= */ NULL, &tmp_path); + if (r < 0) + return r; + + r = link_fd(old_fd, newdirfd, tmp_path); + if (r < 0) { + if (!ERRNO_IS_PRIVILEGE(r)) + return r; + + /* If that didn't work due to permissions then go via the path of the dentry */ + r = RET_NERRNO(linkat(olddirfd, oldpath, newdirfd, tmp_path, 0)); + if (r < 0) + return r; + } + + r = RET_NERRNO(renameat(newdirfd, tmp_path, newdirfd, newpath)); + if (r < 0) { + (void) unlinkat(newdirfd, tmp_path, /* flags= */ 0); + return r; + } + + return 0; +} #endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/fs-util.h b/src/libnm-systemd-shared/src/basic/fs-util.h index 6a1e2e76..eb031a0c 100644 --- a/src/libnm-systemd-shared/src/basic/fs-util.h +++ b/src/libnm-systemd-shared/src/basic/fs-util.h @@ -28,9 +28,11 @@ int rmdir_parents(const char *path, const char *stop); int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath); int readlinkat_malloc(int fd, const char *p, char **ret); -int readlink_malloc(const char *p, char **r); +static inline int readlink_malloc(const char *p, char **ret) { + return readlinkat_malloc(AT_FDCWD, p, ret); +} int readlink_value(const char *p, char **ret); -int readlink_and_make_absolute(const char *p, char **r); +int readlink_and_make_absolute(const char *p, char **ret); int chmod_and_chown_at(int dir_fd, const char *path, mode_t mode, uid_t uid, gid_t gid); static inline int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) { @@ -49,16 +51,21 @@ int futimens_opath(int fd, const struct timespec ts[2]); int fd_warn_permissions(const char *path, int fd); int stat_warn_permissions(const char *path, const struct stat *st); -#define laccess(path, mode) \ +#define access_nofollow(path, mode) \ RET_NERRNO(faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW)) +int touch_fd(int fd, usec_t stamp); + int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode); static inline int touch(const char *path) { return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID); } -int symlink_idempotent(const char *from, const char *to, bool make_relative); +int symlinkat_idempotent(const char *from, int atfd, const char *to, bool make_relative); +static inline int symlink_idempotent(const char *from, const char *to, bool make_relative) { + return symlinkat_idempotent(from, AT_FDCWD, to, make_relative); +} int symlinkat_atomic_full(const char *from, int atfd, const char *to, bool make_relative); static inline int symlink_atomic(const char *from, const char *to) { @@ -105,8 +112,6 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free); int access_fd(int fd, int mode); -void unlink_tempfilep(char (*p)[]); - typedef enum UnlinkDeallocateFlags { UNLINK_REMOVEDIR = 1 << 0, UNLINK_ERASE = 1 << 1, @@ -128,15 +133,23 @@ int posix_fallocate_loop(int fd, uint64_t offset, uint64_t size); int parse_cifs_service(const char *s, char **ret_host, char **ret_service, char **ret_path); -int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode); - -int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, bool *ret_newly_created); - typedef enum XOpenFlags { - XO_LABEL = 1 << 0, - XO_SUBVOLUME = 1 << 1, + XO_LABEL = 1 << 0, /* When creating: relabel */ + XO_SUBVOLUME = 1 << 1, /* When creating as directory: make it a subvolume */ + XO_NOCOW = 1 << 2, /* Enable NOCOW mode after opening */ + XO_REGULAR = 1 << 3, /* Fail if the inode is not a regular file */ } XOpenFlags; +int open_mkdir_at_full(int dirfd, const char *path, int flags, XOpenFlags xopen_flags, mode_t mode); +static inline int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode) { + return open_mkdir_at_full(dirfd, path, flags, 0, mode); +} +static inline int open_mkdir(const char *path, int flags, mode_t mode) { + return open_mkdir_at_full(AT_FDCWD, path, flags, 0, mode); +} + +int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, bool *ret_newly_created); + int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode); static inline int xopenat(int dir_fd, const char *path, int open_flags) { return xopenat_full(dir_fd, path, open_flags, 0, 0); @@ -146,3 +159,16 @@ int xopenat_lock_full(int dir_fd, const char *path, int open_flags, XOpenFlags x static inline int xopenat_lock(int dir_fd, const char *path, int open_flags, LockType locktype, int operation) { return xopenat_lock_full(dir_fd, path, open_flags, 0, 0, locktype, operation); } + +int link_fd(int fd, int newdirfd, const char *newpath); + +int linkat_replace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath); + +static inline int at_flags_normalize_nofollow(int flags) { + if (FLAGS_SET(flags, AT_SYMLINK_FOLLOW)) { + assert(!FLAGS_SET(flags, AT_SYMLINK_NOFOLLOW)); + flags &= ~AT_SYMLINK_FOLLOW; + } else + flags |= AT_SYMLINK_NOFOLLOW; + return flags; +} diff --git a/src/libnm-systemd-shared/src/basic/glyph-util.c b/src/libnm-systemd-shared/src/basic/glyph-util.c index 58d64a03..d38698b6 100644 --- a/src/libnm-systemd-shared/src/basic/glyph-util.c +++ b/src/libnm-systemd-shared/src/basic/glyph-util.c @@ -25,7 +25,7 @@ bool emoji_enabled(void) { return cached_emoji_enabled; } -const char *special_glyph_full(SpecialGlyph code, bool force_utf) { +const char* special_glyph_full(SpecialGlyph code, bool force_utf) { /* A list of a number of interesting unicode glyphs we can use to decorate our output. It's probably wise to be * conservative here, and primarily stick to the glyphs defined in the eurlatgr font, so that display still @@ -82,6 +82,8 @@ const char *special_glyph_full(SpecialGlyph code, bool force_utf) { [SPECIAL_GLYPH_YELLOW_CIRCLE] = "o", [SPECIAL_GLYPH_BLUE_CIRCLE] = "o", [SPECIAL_GLYPH_GREEN_CIRCLE] = "o", + [SPECIAL_GLYPH_SUPERHERO] = "S", + [SPECIAL_GLYPH_IDCARD] = "@", }, /* UTF-8 */ @@ -151,6 +153,8 @@ const char *special_glyph_full(SpecialGlyph code, bool force_utf) { [SPECIAL_GLYPH_YELLOW_CIRCLE] = u8"🟡", [SPECIAL_GLYPH_BLUE_CIRCLE] = u8"🔵", [SPECIAL_GLYPH_GREEN_CIRCLE] = u8"🟢", + [SPECIAL_GLYPH_SUPERHERO] = u8"🦸", + [SPECIAL_GLYPH_IDCARD] = u8"🪪", }, }; diff --git a/src/libnm-systemd-shared/src/basic/glyph-util.h b/src/libnm-systemd-shared/src/basic/glyph-util.h index db8dbbff..ca4d4eda 100644 --- a/src/libnm-systemd-shared/src/basic/glyph-util.h +++ b/src/libnm-systemd-shared/src/basic/glyph-util.h @@ -55,22 +55,24 @@ typedef enum SpecialGlyph { SPECIAL_GLYPH_YELLOW_CIRCLE, SPECIAL_GLYPH_BLUE_CIRCLE, SPECIAL_GLYPH_GREEN_CIRCLE, + SPECIAL_GLYPH_SUPERHERO, + SPECIAL_GLYPH_IDCARD, _SPECIAL_GLYPH_MAX, _SPECIAL_GLYPH_INVALID = -EINVAL, } SpecialGlyph; bool emoji_enabled(void); -const char *special_glyph_full(SpecialGlyph code, bool force_utf) _const_; +const char* special_glyph_full(SpecialGlyph code, bool force_utf) _const_; -static inline const char *special_glyph(SpecialGlyph code) { +static inline const char* special_glyph(SpecialGlyph code) { return special_glyph_full(code, false); } -static inline const char *special_glyph_check_mark(bool b) { +static inline const char* special_glyph_check_mark(bool b) { return b ? special_glyph(SPECIAL_GLYPH_CHECK_MARK) : special_glyph(SPECIAL_GLYPH_CROSS_MARK); } -static inline const char *special_glyph_check_mark_space(bool b) { +static inline const char* special_glyph_check_mark_space(bool b) { return b ? special_glyph(SPECIAL_GLYPH_CHECK_MARK) : " "; } diff --git a/src/libnm-systemd-shared/src/basic/hashmap.c b/src/libnm-systemd-shared/src/basic/hashmap.c index 9686af0d..6b0247c3 100644 --- a/src/libnm-systemd-shared/src/basic/hashmap.c +++ b/src/libnm-systemd-shared/src/basic/hashmap.c @@ -878,6 +878,26 @@ int _ordered_hashmap_ensure_put(OrderedHashmap **h, const struct hash_ops *hash_ return ordered_hashmap_put(*h, key, value); } +int _ordered_hashmap_ensure_replace(OrderedHashmap **h, const struct hash_ops *hash_ops, const void *key, void *value HASHMAP_DEBUG_PARAMS) { + int r; + + r = _ordered_hashmap_ensure_allocated(h, hash_ops HASHMAP_DEBUG_PASS_ARGS); + if (r < 0) + return r; + + return ordered_hashmap_replace(*h, key, value); +} + +int _hashmap_ensure_replace(Hashmap **h, const struct hash_ops *hash_ops, const void *key, void *value HASHMAP_DEBUG_PARAMS) { + int r; + + r = _hashmap_ensure_allocated(h, hash_ops HASHMAP_DEBUG_PASS_ARGS); + if (r < 0) + return r; + + return hashmap_replace(*h, key, value); +} + static void hashmap_free_no_clear(HashmapBase *h) { assert(!h->has_indirect); assert(h->n_direct_entries == 0); diff --git a/src/libnm-systemd-shared/src/basic/hashmap.h b/src/libnm-systemd-shared/src/basic/hashmap.h index 49d9d118..01a4fb32 100644 --- a/src/libnm-systemd-shared/src/basic/hashmap.h +++ b/src/libnm-systemd-shared/src/basic/hashmap.h @@ -130,14 +130,19 @@ HashmapBase* _hashmap_copy(HashmapBase *h HASHMAP_DEBUG_PARAMS); int _hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); int _hashmap_ensure_put(Hashmap **h, const struct hash_ops *hash_ops, const void *key, void *value HASHMAP_DEBUG_PARAMS); int _ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); +int _hashmap_ensure_replace(Hashmap **h, const struct hash_ops *hash_ops, const void *key, void *value HASHMAP_DEBUG_PARAMS); #define hashmap_ensure_allocated(h, ops) _hashmap_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS) #define hashmap_ensure_put(s, ops, key, value) _hashmap_ensure_put(s, ops, key, value HASHMAP_DEBUG_SRC_ARGS) #define ordered_hashmap_ensure_allocated(h, ops) _ordered_hashmap_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS) +#define hashmap_ensure_replace(s, ops, key, value) _hashmap_ensure_replace(s, ops, key, value HASHMAP_DEBUG_SRC_ARGS) int _ordered_hashmap_ensure_put(OrderedHashmap **h, const struct hash_ops *hash_ops, const void *key, void *value HASHMAP_DEBUG_PARAMS); #define ordered_hashmap_ensure_put(s, ops, key, value) _ordered_hashmap_ensure_put(s, ops, key, value HASHMAP_DEBUG_SRC_ARGS) +int _ordered_hashmap_ensure_replace(OrderedHashmap **h, const struct hash_ops *hash_ops, const void *key, void *value HASHMAP_DEBUG_PARAMS); +#define ordered_hashmap_ensure_replace(s, ops, key, value) _ordered_hashmap_ensure_replace(s, ops, key, value HASHMAP_DEBUG_SRC_ARGS) + IteratedCache* _hashmap_iterated_cache_new(HashmapBase *h); static inline IteratedCache* hashmap_iterated_cache_new(Hashmap *h) { return (IteratedCache*) _hashmap_iterated_cache_new(HASHMAP_BASE(h)); diff --git a/src/libnm-systemd-shared/src/basic/hexdecoct.c b/src/libnm-systemd-shared/src/basic/hexdecoct.c index 41228520..1acff812 100644 --- a/src/libnm-systemd-shared/src/basic/hexdecoct.c +++ b/src/libnm-systemd-shared/src/basic/hexdecoct.c @@ -38,7 +38,7 @@ int undecchar(char c) { } char hexchar(int x) { - static const char table[16] = "0123456789abcdef"; + static const char table[] = "0123456789abcdef"; return table[x & 15]; } @@ -57,7 +57,7 @@ int unhexchar(char c) { return -EINVAL; } -char *hexmem(const void *p, size_t l) { +char* hexmem(const void *p, size_t l) { const uint8_t *x; char *r, *z; @@ -171,8 +171,8 @@ int unhexmem_full( * useful when representing NSEC3 hashes, as one can then verify the * order of hashes directly from their representation. */ char base32hexchar(int x) { - static const char table[32] = "0123456789" - "ABCDEFGHIJKLMNOPQRSTUV"; + static const char table[] = "0123456789" + "ABCDEFGHIJKLMNOPQRSTUV"; return table[x & 31]; } @@ -191,7 +191,7 @@ int unbase32hexchar(char c) { return -EINVAL; } -char *base32hexmem(const void *p, size_t l, bool padding) { +char* base32hexmem(const void *p, size_t l, bool padding) { char *r, *z; const uint8_t *x; size_t len; @@ -522,9 +522,9 @@ int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_l /* https://tools.ietf.org/html/rfc4648#section-4 */ char base64char(int x) { - static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; + static const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; return table[x & 63]; } #endif /* NM_IGNORED */ @@ -533,9 +533,9 @@ char base64char(int x) { * since we don't want "/" appear in interface names (since interfaces appear in sysfs as filenames). * See section #5 of RFC 4648. */ char urlsafe_base64char(int x) { - static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789-_"; + static const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789-_"; return table[x & 63]; } @@ -873,6 +873,9 @@ void hexdump(FILE *f, const void *p, size_t s) { assert(b || s == 0); + if (s == SIZE_MAX) + s = strlen(p); + if (!f) f = stdout; diff --git a/src/libnm-systemd-shared/src/basic/hexdecoct.h b/src/libnm-systemd-shared/src/basic/hexdecoct.h index 0a10af3e..d160ca28 100644 --- a/src/libnm-systemd-shared/src/basic/hexdecoct.h +++ b/src/libnm-systemd-shared/src/basic/hexdecoct.h @@ -17,7 +17,7 @@ int undecchar(char c) _const_; char hexchar(int x) _const_; int unhexchar(char c) _const_; -char *hexmem(const void *p, size_t l); +char* hexmem(const void *p, size_t l); int unhexmem_full(const char *p, size_t l, bool secure, void **ret_data, size_t *ret_size); static inline int unhexmem(const char *p, void **ret_data, size_t *ret_size) { return unhexmem_full(p, SIZE_MAX, false, ret_data, ret_size); @@ -30,7 +30,7 @@ char base64char(int x) _const_; char urlsafe_base64char(int x) _const_; int unbase64char(char c) _const_; -char *base32hexmem(const void *p, size_t l, bool padding); +char* base32hexmem(const void *p, size_t l, bool padding); int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *len); ssize_t base64mem_full(const void *p, size_t l, size_t line_break, char **ret); diff --git a/src/libnm-systemd-shared/src/basic/in-addr-util.c b/src/libnm-systemd-shared/src/basic/in-addr-util.c index 310e057a..44445f1e 100644 --- a/src/libnm-systemd-shared/src/basic/in-addr-util.c +++ b/src/libnm-systemd-shared/src/basic/in-addr-util.c @@ -197,58 +197,69 @@ int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_ } #if 0 /* NM_IGNORED */ -int in_addr_prefix_intersect( - int family, - const union in_addr_union *a, +bool in4_addr_prefix_intersect( + const struct in_addr *a, unsigned aprefixlen, - const union in_addr_union *b, + const struct in_addr *b, unsigned bprefixlen) { - unsigned m; - assert(a); assert(b); - /* Checks whether there are any addresses that are in both networks */ + unsigned m = MIN3(aprefixlen, bprefixlen, (unsigned) (sizeof(struct in_addr) * 8)); + if (m == 0) + return true; /* Let's return earlier, to avoid shift by 32. */ - m = MIN(aprefixlen, bprefixlen); + uint32_t x = be32toh(a->s_addr ^ b->s_addr); + uint32_t n = 0xFFFFFFFFUL << (32 - m); + return (x & n) == 0; +} - if (family == AF_INET) { - uint32_t x, nm; +bool in6_addr_prefix_intersect( + const struct in6_addr *a, + unsigned aprefixlen, + const struct in6_addr *b, + unsigned bprefixlen) { - x = be32toh(a->in.s_addr ^ b->in.s_addr); - nm = m == 0 ? 0 : 0xFFFFFFFFUL << (32 - m); + assert(a); + assert(b); - return (x & nm) == 0; - } + unsigned m = MIN3(aprefixlen, bprefixlen, (unsigned) (sizeof(struct in6_addr) * 8)); + if (m == 0) + return true; - if (family == AF_INET6) { - unsigned i; + for (size_t i = 0; i < sizeof(struct in6_addr); i++) { + uint8_t x = a->s6_addr[i] ^ b->s6_addr[i]; + uint8_t n = m < 8 ? (0xFF << (8 - m)) : 0xFF; + if ((x & n) != 0) + return false; - if (m > 128) - m = 128; + if (m <= 8) + break; - for (i = 0; i < 16; i++) { - uint8_t x, nm; + m -= 8; + } - x = a->in6.s6_addr[i] ^ b->in6.s6_addr[i]; + return true; +} - if (m < 8) - nm = 0xFF << (8 - m); - else - nm = 0xFF; +int in_addr_prefix_intersect( + int family, + const union in_addr_union *a, + unsigned aprefixlen, + const union in_addr_union *b, + unsigned bprefixlen) { + + assert(a); + assert(b); - if ((x & nm) != 0) - return 0; + /* Checks whether there are any addresses that are in both networks. */ - if (m > 8) - m -= 8; - else - m = 0; - } + if (family == AF_INET) + return in4_addr_prefix_intersect(&a->in, aprefixlen, &b->in, bprefixlen); - return 1; - } + if (family == AF_INET6) + return in6_addr_prefix_intersect(&a->in6, aprefixlen, &b->in6, bprefixlen); return -EAFNOSUPPORT; } @@ -888,7 +899,7 @@ int in_addr_prefix_from_string( return 0; } -int in_addr_prefix_from_string_auto_internal( +int in_addr_prefix_from_string_auto_full( const char *p, InAddrPrefixLenMode mode, int *ret_family, diff --git a/src/libnm-systemd-shared/src/basic/in-addr-util.h b/src/libnm-systemd-shared/src/basic/in-addr-util.h index 5c820c6e..2efe9aec 100644 --- a/src/libnm-systemd-shared/src/basic/in-addr-util.h +++ b/src/libnm-systemd-shared/src/basic/in-addr-util.h @@ -61,7 +61,22 @@ bool in6_addr_is_ipv4_mapped_address(const struct in6_addr *a); bool in4_addr_equal(const struct in_addr *a, const struct in_addr *b); bool in6_addr_equal(const struct in6_addr *a, const struct in6_addr *b); int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b); -int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen); +bool in4_addr_prefix_intersect( + const struct in_addr *a, + unsigned aprefixlen, + const struct in_addr *b, + unsigned bprefixlen); +bool in6_addr_prefix_intersect( + const struct in6_addr *a, + unsigned aprefixlen, + const struct in6_addr *b, + unsigned bprefixlen); +int in_addr_prefix_intersect( + int family, + const union in_addr_union *a, + unsigned aprefixlen, + const union in_addr_union *b, + unsigned bprefixlen); int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen); int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, uint64_t nth); int in_addr_random_prefix(int family, union in_addr_union *u, unsigned prefixlen_fixed_part, unsigned prefixlen); @@ -166,9 +181,9 @@ typedef enum InAddrPrefixLenMode { PREFIXLEN_REFUSE, /* Fail with -ENOANO if prefixlen is not specified. */ } InAddrPrefixLenMode; -int in_addr_prefix_from_string_auto_internal(const char *p, InAddrPrefixLenMode mode, int *ret_family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen); +int in_addr_prefix_from_string_auto_full(const char *p, InAddrPrefixLenMode mode, int *ret_family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen); static inline int in_addr_prefix_from_string_auto(const char *p, int *ret_family, union in_addr_union *ret_prefix, unsigned char *ret_prefixlen) { - return in_addr_prefix_from_string_auto_internal(p, PREFIXLEN_FULL, ret_family, ret_prefix, ret_prefixlen); + return in_addr_prefix_from_string_auto_full(p, PREFIXLEN_FULL, ret_family, ret_prefix, ret_prefixlen); } static inline size_t FAMILY_ADDRESS_SIZE(int family) { diff --git a/src/libnm-systemd-shared/src/basic/inotify-util.c b/src/libnm-systemd-shared/src/basic/inotify-util.c index c748bf1b..14e012ab 100644 --- a/src/libnm-systemd-shared/src/basic/inotify-util.c +++ b/src/libnm-systemd-shared/src/basic/inotify-util.c @@ -44,7 +44,10 @@ bool inotify_event_next( } int inotify_add_watch_fd(int fd, int what, uint32_t mask) { - int wd, r; + int wd; + + assert(fd >= 0); + assert(what >= 0); /* This is like inotify_add_watch(), except that the file to watch is not referenced by a path, but by an fd */ wd = inotify_add_watch(fd, FORMAT_PROC_FD_PATH(what), mask); @@ -52,14 +55,7 @@ int inotify_add_watch_fd(int fd, int what, uint32_t mask) { if (errno != ENOENT) return -errno; - /* Didn't work with ENOENT? If so, then either /proc/ isn't mounted, or the fd is bad */ - r = proc_mounted(); - if (r == 0) - return -ENOSYS; - if (r > 0) - return -EBADF; - - return -ENOENT; /* OK, no clue, let's propagate the original error */ + return proc_fd_enoent_errno(); } return wd; diff --git a/src/libnm-systemd-shared/src/basic/iovec-util.h b/src/libnm-systemd-shared/src/basic/iovec-util.h index 8cfa5717..86845404 100644 --- a/src/libnm-systemd-shared/src/basic/iovec-util.h +++ b/src/libnm-systemd-shared/src/basic/iovec-util.h @@ -6,25 +6,16 @@ #include <sys/uio.h> #include "alloc-util.h" +#include "iovec-util-fundamental.h" #include "macro.h" -/* An iovec pointing to a single NUL byte */ -#define IOVEC_NUL_BYTE (const struct iovec) { \ - .iov_base = (void*) (const uint8_t[1]) { 0 }, \ - .iov_len = 1, \ - } +extern const struct iovec iovec_nul_byte; /* Points to a single NUL byte */ +extern const struct iovec iovec_empty; /* Points to an empty, but valid (i.e. non-NULL) pointer */ size_t iovec_total_size(const struct iovec *iovec, size_t n); bool iovec_increment(struct iovec *iovec, size_t n, size_t k); -/* This accepts both const and non-const pointers */ -#define IOVEC_MAKE(base, len) \ - (struct iovec) { \ - .iov_base = (void*) (base), \ - .iov_len = (len), \ - } - static inline struct iovec* iovec_make_string(struct iovec *iovec, const char *s) { assert(iovec); /* We don't use strlen_ptr() here, because we don't want to include string-util.h for now */ @@ -41,14 +32,6 @@ static inline struct iovec* iovec_make_string(struct iovec *iovec, const char *s .iov_len = STRLEN(s), \ } -static inline void iovec_done(struct iovec *iovec) { - /* A _cleanup_() helper that frees the iov_base in the iovec */ - assert(iovec); - - iovec->iov_base = mfree(iovec->iov_base); - iovec->iov_len = 0; -} - static inline void iovec_done_erase(struct iovec *iovec) { assert(iovec); @@ -56,16 +39,6 @@ static inline void iovec_done_erase(struct iovec *iovec) { iovec->iov_len = 0; } -static inline bool iovec_is_set(const struct iovec *iovec) { - /* Checks if the iovec points to a non-empty chunk of memory */ - return iovec && iovec->iov_len > 0 && iovec->iov_base; -} - -static inline bool iovec_is_valid(const struct iovec *iovec) { - /* Checks if the iovec is either NULL, empty or points to a valid bit of memory */ - return !iovec || (iovec->iov_base || iovec->iov_len == 0); -} - char* set_iovec_string_field(struct iovec *iovec, size_t *n_iovec, const char *field, const char *value); char* set_iovec_string_field_free(struct iovec *iovec, size_t *n_iovec, const char *field, char *value); @@ -97,3 +70,5 @@ static inline struct iovec *iovec_memdup(const struct iovec *source, struct iove return ret; } + +struct iovec* iovec_append(struct iovec *iovec, const struct iovec *append); diff --git a/src/libnm-systemd-shared/src/basic/label.c b/src/libnm-systemd-shared/src/basic/label.c index a08a238f..ab78f85d 100644 --- a/src/libnm-systemd-shared/src/basic/label.c +++ b/src/libnm-systemd-shared/src/basic/label.c @@ -6,10 +6,13 @@ #include <stddef.h> #include "label.h" +#include "macro.h" static const LabelOps *label_ops = NULL; int label_ops_set(const LabelOps *ops) { + assert(ops); + if (label_ops) return -EBUSY; @@ -17,6 +20,10 @@ int label_ops_set(const LabelOps *ops) { return 0; } +void label_ops_reset(void) { + label_ops = NULL; +} + int label_ops_pre(int dir_fd, const char *path, mode_t mode) { if (!label_ops || !label_ops->pre) return 0; @@ -24,9 +31,9 @@ int label_ops_pre(int dir_fd, const char *path, mode_t mode) { return label_ops->pre(dir_fd, path, mode); } -int label_ops_post(int dir_fd, const char *path) { +int label_ops_post(int dir_fd, const char *path, bool created) { if (!label_ops || !label_ops->post) return 0; - return label_ops->post(dir_fd, path); + return label_ops->post(dir_fd, path, created); } diff --git a/src/libnm-systemd-shared/src/basic/label.h b/src/libnm-systemd-shared/src/basic/label.h index 9644e435..d001307a 100644 --- a/src/libnm-systemd-shared/src/basic/label.h +++ b/src/libnm-systemd-shared/src/basic/label.h @@ -1,14 +1,16 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include <stdbool.h> #include <sys/types.h> typedef struct LabelOps { int (*pre)(int dir_fd, const char *path, mode_t mode); - int (*post)(int dir_fd, const char *path); + int (*post)(int dir_fd, const char *path, bool created); } LabelOps; int label_ops_set(const LabelOps *label_ops); +void label_ops_reset(void); int label_ops_pre(int dir_fd, const char *path, mode_t mode); -int label_ops_post(int dir_fd, const char *path); +int label_ops_post(int dir_fd, const char *path, bool created); diff --git a/src/libnm-systemd-shared/src/basic/locale-util.c b/src/libnm-systemd-shared/src/basic/locale-util.c index 95648775..0654fde8 100644 --- a/src/libnm-systemd-shared/src/basic/locale-util.c +++ b/src/libnm-systemd-shared/src/basic/locale-util.c @@ -279,8 +279,7 @@ int locale_is_installed(const char *name) { if (STR_IN_SET(name, "C", "POSIX")) /* These ones are always OK */ return true; - _cleanup_(freelocalep) locale_t loc = - newlocale(LC_ALL_MASK, name, 0); + _cleanup_(freelocalep) locale_t loc = newlocale(LC_ALL_MASK, name, (locale_t) 0); if (loc == (locale_t) 0) return errno == ENOMEM ? -ENOMEM : false; diff --git a/src/libnm-systemd-shared/src/basic/lock-util.h b/src/libnm-systemd-shared/src/basic/lock-util.h index 91b332f8..a67d8b2c 100644 --- a/src/libnm-systemd-shared/src/basic/lock-util.h +++ b/src/libnm-systemd-shared/src/basic/lock-util.h @@ -2,6 +2,8 @@ #pragma once #include <fcntl.h> +/* Include here so consumers have LOCK_{EX,SH,NB} available. */ +#include <sys/file.h> typedef struct LockFile { int dir_fd; @@ -17,7 +19,7 @@ static inline int make_lock_file(const char *p, int operation, LockFile *ret) { int make_lock_file_for(const char *p, int operation, LockFile *ret); void release_lock_file(LockFile *f); -#define LOCK_FILE_INIT { .dir_fd = -EBADF, .fd = -EBADF } +#define LOCK_FILE_INIT (LockFile) { .dir_fd = -EBADF, .fd = -EBADF } /* POSIX locks with the same interface as flock(). */ int posix_lock(int fd, int operation); diff --git a/src/libnm-systemd-shared/src/basic/log.h b/src/libnm-systemd-shared/src/basic/log.h index 1b5bc655..6477bff4 100644 --- a/src/libnm-systemd-shared/src/basic/log.h +++ b/src/libnm-systemd-shared/src/basic/log.h @@ -18,25 +18,26 @@ struct signalfd_siginfo; typedef enum LogTarget{ LOG_TARGET_CONSOLE, - LOG_TARGET_CONSOLE_PREFIXED, LOG_TARGET_KMSG, LOG_TARGET_JOURNAL, - LOG_TARGET_JOURNAL_OR_KMSG, LOG_TARGET_SYSLOG, + LOG_TARGET_CONSOLE_PREFIXED, + LOG_TARGET_JOURNAL_OR_KMSG, LOG_TARGET_SYSLOG_OR_KMSG, LOG_TARGET_AUTO, /* console if stderr is not journal, JOURNAL_OR_KMSG otherwise */ LOG_TARGET_NULL, - _LOG_TARGET_MAX, + _LOG_TARGET_SINGLE_MAX = LOG_TARGET_SYSLOG + 1, + _LOG_TARGET_MAX = LOG_TARGET_NULL + 1, _LOG_TARGET_INVALID = -EINVAL, } LogTarget; /* This log level disables logging completely. It can only be passed to log_set_max_level() and cannot be - * used a regular log level. */ + * used as a regular log level. */ #define LOG_NULL (LOG_EMERG - 1) +assert_cc(LOG_NULL == -1); -/* Note to readers: << and >> have lower precedence (are evaluated earlier) than & and | */ -#define SYNTHETIC_ERRNO(num) (1 << 30 | (num)) -#define IS_SYNTHETIC_ERRNO(val) ((val) >> 30 & 1) +#define SYNTHETIC_ERRNO(num) (abs(num) | (1 << 30)) +#define IS_SYNTHETIC_ERRNO(val) (((val) >> 30) == 1) #define ERRNO_VALUE(val) (abs(val) & ~(1 << 30)) /* The callback function to be invoked when syntax warnings are seen @@ -48,7 +49,7 @@ static inline void clear_log_syntax_callback(dummy_t *dummy) { set_log_syntax_callback(/* cb= */ NULL, /* userdata= */ NULL); } -const char *log_target_to_string(LogTarget target) _const_; +const char* log_target_to_string(LogTarget target) _const_; LogTarget log_target_from_string(const char *s) _pure_; void log_set_target(LogTarget target); void log_set_target_and_open(LogTarget target); @@ -56,7 +57,7 @@ int log_set_target_from_string(const char *e); LogTarget log_get_target(void) _pure_; void log_settle_target(void); -void log_set_max_level(int level); +int log_set_max_level(int level); int log_set_max_level_from_string(const char *e); #if 0 /* NM_IGNORED */ int log_get_max_level(void) _pure_; @@ -67,6 +68,7 @@ log_get_max_level(void) return 7 /* LOG_DEBUG */; } #endif /* NM_IGNORED */ +int log_max_levels_to_string(int level, char **ret); void log_set_facility(int facility); @@ -95,6 +97,7 @@ assert_cc(STRLEN(__FILE__) > STRLEN(RELATIVE_SOURCE_PATH) + 1); #define PROJECT_FILE __FILE__ #endif /* NM_IGNORED */ +bool stderr_is_journal(void); int log_open(void); void log_close(void); void log_forget_fds(void); @@ -434,9 +437,10 @@ int log_emergency_level(void); #define log_dump(level, buffer) \ log_dump_internal(level, 0, PROJECT_FILE, __LINE__, __func__, buffer) -#define log_oom() log_oom_internal(LOG_ERR, PROJECT_FILE, __LINE__, __func__) -#define log_oom_debug() log_oom_internal(LOG_DEBUG, PROJECT_FILE, __LINE__, __func__) -#define log_oom_warning() log_oom_internal(LOG_WARNING, PROJECT_FILE, __LINE__, __func__) +#define log_oom_full(level) log_oom_internal(level, PROJECT_FILE, __LINE__, __func__) +#define log_oom() log_oom_full(LOG_ERR) +#define log_oom_debug() log_oom_full(LOG_DEBUG) +#define log_oom_warning() log_oom_full(LOG_WARNING) bool log_on_console(void) _pure_; @@ -498,6 +502,18 @@ int log_syntax_invalid_utf8_internal( const char *func, const char *rvalue); +int log_syntax_parse_error_internal( + const char *unit, + const char *config_file, + unsigned config_line, + int error, + bool critical, /* When true, propagate the passed error, otherwise this always returns 0. */ + const char *file, + int line, + const char *func, + const char *lvalue, + const char *rvalue); + #define log_syntax(unit, level, config_file, config_line, error, ...) \ ({ \ int _level = (level), _e = (error); \ @@ -514,6 +530,12 @@ int log_syntax_invalid_utf8_internal( : -EINVAL; \ }) +#define log_syntax_parse_error_full(unit, config_file, config_line, error, critical, lvalue, rvalue) \ + log_syntax_parse_error_internal(unit, config_file, config_line, error, critical, PROJECT_FILE, __LINE__, __func__, lvalue, rvalue) + +#define log_syntax_parse_error(unit, config_file, config_line, error, lvalue, rvalue) \ + log_syntax_parse_error_full(unit, config_file, config_line, error, /* critical = */ false, lvalue, rvalue) + #define DEBUG_LOGGING _unlikely_(log_get_max_level() >= LOG_DEBUG) void log_setup(void); @@ -570,8 +592,8 @@ typedef struct LogRateLimit { #define log_ratelimit_error_errno(error, ...) log_ratelimit_full_errno(LOG_ERR, error, __VA_ARGS__) #define log_ratelimit_emergency_errno(error, ...) log_ratelimit_full_errno(log_emergency_level(), error, __VA_ARGS__) -const char *_log_set_prefix(const char *prefix, bool force); -static inline const char *_log_unset_prefixp(const char **p) { +const char* _log_set_prefix(const char *prefix, bool force); +static inline const char* _log_unset_prefixp(const char **p) { assert(p); _log_set_prefix(*p, true); return NULL; @@ -630,6 +652,15 @@ size_t log_context_num_contexts(void); /* Returns the number of fields in all attached log contexts. */ size_t log_context_num_fields(void); +static inline void _reset_log_level(int *saved_log_level) { + assert(saved_log_level); + + log_set_max_level(*saved_log_level); +} + +#define LOG_CONTEXT_SET_LOG_LEVEL(level) \ + _cleanup_(_reset_log_level) _unused_ int _saved_log_level_ = log_set_max_level(level); + #define LOG_CONTEXT_PUSH(...) \ LOG_CONTEXT_PUSH_STRV(STRV_MAKE(__VA_ARGS__)) diff --git a/src/libnm-systemd-shared/src/basic/macro.h b/src/libnm-systemd-shared/src/basic/macro.h index eec8cba6..026ec136 100644 --- a/src/libnm-systemd-shared/src/basic/macro.h +++ b/src/libnm-systemd-shared/src/basic/macro.h @@ -30,60 +30,6 @@ #define _function_no_sanitize_float_cast_overflow_ #endif -#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))) || defined (__clang__) -/* Temporarily disable some warnings */ -#define DISABLE_WARNING_DEPRECATED_DECLARATIONS \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") - -#define DISABLE_WARNING_FORMAT_NONLITERAL \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") - -#define DISABLE_WARNING_MISSING_PROTOTYPES \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"") - -#define DISABLE_WARNING_NONNULL \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wnonnull\"") - -#define DISABLE_WARNING_SHADOW \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wshadow\"") - -#define DISABLE_WARNING_INCOMPATIBLE_POINTER_TYPES \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wincompatible-pointer-types\"") - -#if HAVE_WSTRINGOP_TRUNCATION -# define DISABLE_WARNING_STRINGOP_TRUNCATION \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wstringop-truncation\"") -#else -# define DISABLE_WARNING_STRINGOP_TRUNCATION \ - _Pragma("GCC diagnostic push") -#endif - -#define DISABLE_WARNING_TYPE_LIMITS \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") - -#define DISABLE_WARNING_ADDRESS \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Waddress\"") - -#define REENABLE_WARNING \ - _Pragma("GCC diagnostic pop") -#else -#define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT -#define DISABLE_WARNING_FORMAT_NONLITERAL -#define DISABLE_WARNING_MISSING_PROTOTYPES -#define DISABLE_WARNING_NONNULL -#define DISABLE_WARNING_SHADOW -#define REENABLE_WARNING -#endif - /* test harness */ #define EXIT_TEST_SKIP 77 @@ -256,16 +202,10 @@ static inline int __coverity_check_and_return__(int condition) { #define PTR_TO_UINT64(p) ((uint64_t) ((uintptr_t) (p))) #define UINT64_TO_PTR(u) ((void *) ((uintptr_t) (u))) -#define PTR_TO_SIZE(p) ((size_t) ((uintptr_t) (p))) -#define SIZE_TO_PTR(u) ((void *) ((uintptr_t) (u))) - #define CHAR_TO_STR(x) ((char[2]) { x, 0 }) #define char_array_0(x) x[sizeof(x)-1] = 0; -#define sizeof_field(struct_type, member) sizeof(((struct_type *) 0)->member) -#define endoffsetof_field(struct_type, member) (offsetof(struct_type, member) + sizeof_field(struct_type, member)) - /* Maximum buffer size needed for formatting an unsigned integer type as hex, including space for '0x' * prefix and trailing NUL suffix. */ #define HEXADECIMAL_STR_MAX(type) (2 + sizeof(type) * 2 + 1) @@ -311,15 +251,6 @@ static inline int __coverity_check_and_return__(int condition) { /* Pointers range from NULL to POINTER_MAX */ #define POINTER_MAX ((void*) UINTPTR_MAX) -#define _FOREACH_ARRAY(i, array, num, m, end) \ - for (typeof(array[0]) *i = (array), *end = ({ \ - typeof(num) m = (num); \ - (i && m > 0) ? i + m : NULL; \ - }); end && i < end; i++) - -#define FOREACH_ARRAY(i, array, num) \ - _FOREACH_ARRAY(i, array, num, UNIQ_T(m, UNIQ), UNIQ_T(end, UNIQ)) - #define _DEFINE_TRIVIAL_REF_FUNC(type, name, scope) \ scope type *name##_ref(type *p) { \ if (!p) \ diff --git a/src/libnm-systemd-shared/src/basic/memory-util.h b/src/libnm-systemd-shared/src/basic/memory-util.h index 294aed67..1f604cc4 100644 --- a/src/libnm-systemd-shared/src/basic/memory-util.h +++ b/src/libnm-systemd-shared/src/basic/memory-util.h @@ -20,7 +20,7 @@ size_t page_size(void) _pure_; #define PAGE_OFFSET_U64(l) ALIGN_OFFSET_U64(l, page_size()) /* Normal memcpy() requires src to be nonnull. We do nothing if n is 0. */ -static inline void *memcpy_safe(void *dst, const void *src, size_t n) { +static inline void* memcpy_safe(void *dst, const void *src, size_t n) { if (n == 0) return dst; assert(src); @@ -28,13 +28,20 @@ static inline void *memcpy_safe(void *dst, const void *src, size_t n) { } /* Normal mempcpy() requires src to be nonnull. We do nothing if n is 0. */ -static inline void *mempcpy_safe(void *dst, const void *src, size_t n) { +static inline void* mempcpy_safe(void *dst, const void *src, size_t n) { if (n == 0) return dst; assert(src); return mempcpy(dst, src, n); } +#define mempcpy_typesafe(dst, src, n) \ + ({ \ + size_t _sz_; \ + assert_se(MUL_SAFE(&_sz_, sizeof((dst)[0]), n)); \ + (typeof((dst)[0])*) mempcpy_safe(dst, src, _sz_); \ + }) + /* Normal memcmp() requires s1 and s2 to be nonnull. We do nothing if n is 0. */ static inline int memcmp_safe(const void *s1, const void *s2, size_t n) { if (n == 0) diff --git a/src/libnm-systemd-shared/src/basic/missing_fcntl.h b/src/libnm-systemd-shared/src/basic/missing_fcntl.h index 3c85befd..a6188879 100644 --- a/src/libnm-systemd-shared/src/basic/missing_fcntl.h +++ b/src/libnm-systemd-shared/src/basic/missing_fcntl.h @@ -7,6 +7,10 @@ #define F_LINUX_SPECIFIC_BASE 1024 #endif +#ifndef F_DUPFD_QUERY +#define F_DUPFD_QUERY (F_LINUX_SPECIFIC_BASE + 3) +#endif + #ifndef F_SETPIPE_SZ #define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7) #endif @@ -92,3 +96,7 @@ #define RAW_O_LARGEFILE 00100000 #endif #endif + +#ifndef AT_HANDLE_FID +#define AT_HANDLE_FID AT_REMOVEDIR +#endif diff --git a/src/libnm-systemd-shared/src/basic/missing_pidfd.h b/src/libnm-systemd-shared/src/basic/missing_pidfd.h new file mode 100644 index 00000000..4c815142 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/missing_pidfd.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include <linux/types.h> +#if HAVE_PIDFD_OPEN +#include <sys/pidfd.h> +#endif + +#ifndef PIDFS_IOCTL_MAGIC +# define PIDFS_IOCTL_MAGIC 0xFF +#endif + +#ifndef PIDFD_GET_CGROUP_NAMESPACE +# define PIDFD_GET_CGROUP_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 1) +# define PIDFD_GET_IPC_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 2) +# define PIDFD_GET_MNT_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 3) +# define PIDFD_GET_NET_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 4) +# define PIDFD_GET_PID_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 5) +# define PIDFD_GET_PID_FOR_CHILDREN_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 6) +# define PIDFD_GET_TIME_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 7) +# define PIDFD_GET_TIME_FOR_CHILDREN_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 8) +# define PIDFD_GET_USER_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 9) +# define PIDFD_GET_UTS_NAMESPACE _IO(PIDFS_IOCTL_MAGIC, 10) +#endif + +#ifndef PIDFD_GET_INFO +struct pidfd_info { + __u64 mask; + __u64 cgroupid; + __u32 pid; + __u32 tgid; + __u32 ppid; + __u32 ruid; + __u32 rgid; + __u32 euid; + __u32 egid; + __u32 suid; + __u32 sgid; + __u32 fsuid; + __u32 fsgid; + __u32 spare0[1]; +}; + +#define PIDFD_GET_INFO _IOWR(PIDFS_IOCTL_MAGIC, 11, struct pidfd_info) +#define PIDFD_INFO_PID (1UL << 0) +#define PIDFD_INFO_CREDS (1UL << 1) +#define PIDFD_INFO_CGROUPID (1UL << 2) +#endif diff --git a/src/libnm-systemd-shared/src/basic/missing_random.h b/src/libnm-systemd-shared/src/basic/missing_random.h index 443b9136..5f40c4e5 100644 --- a/src/libnm-systemd-shared/src/basic/missing_random.h +++ b/src/libnm-systemd-shared/src/basic/missing_random.h @@ -1,20 +1,28 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#if USE_SYS_RANDOM_H +#include "macro.h" + +#if HAVE_GETRANDOM # include <sys/random.h> #else # include <linux/random.h> #endif #ifndef GRND_NONBLOCK -#define GRND_NONBLOCK 0x0001 +# define GRND_NONBLOCK 0x0001 +#else +assert_cc(GRND_NONBLOCK == 0x0001); #endif #ifndef GRND_RANDOM -#define GRND_RANDOM 0x0002 +# define GRND_RANDOM 0x0002 +#else +assert_cc(GRND_RANDOM == 0x0002); #endif #ifndef GRND_INSECURE -#define GRND_INSECURE 0x0004 +# define GRND_INSECURE 0x0004 +#else +assert_cc(GRND_INSECURE == 0x0004); #endif diff --git a/src/libnm-systemd-shared/src/basic/missing_socket.h b/src/libnm-systemd-shared/src/basic/missing_socket.h index ffda7cc6..8460ce13 100644 --- a/src/libnm-systemd-shared/src/basic/missing_socket.h +++ b/src/libnm-systemd-shared/src/basic/missing_socket.h @@ -3,44 +3,6 @@ #include <sys/socket.h> -#if 0 /* NM_IGNORED */ -#if HAVE_LINUX_VM_SOCKETS_H -#include <linux/vm_sockets.h> -#else -struct sockaddr_vm { - unsigned short svm_family; - unsigned short svm_reserved1; - unsigned int svm_port; - unsigned int svm_cid; - unsigned char svm_zero[sizeof(struct sockaddr) - - sizeof(unsigned short) - - sizeof(unsigned short) - - sizeof(unsigned int) - - sizeof(unsigned int)]; -}; -#endif /* !HAVE_LINUX_VM_SOCKETS_H */ -#endif /* NM_IGNORED */ - -#ifndef VMADDR_CID_ANY -#define VMADDR_CID_ANY -1U -#endif - -#ifndef VMADDR_CID_HYPERVISOR -#define VMADDR_CID_HYPERVISOR 0U -#endif - -#ifndef VMADDR_CID_LOCAL -#define VMADDR_CID_LOCAL 1U -#endif - -#ifndef VMADDR_CID_HOST -#define VMADDR_CID_HOST 2U -#endif - -#ifndef VMADDR_PORT_ANY -#define VMADDR_PORT_ANY -1U -#endif - #ifndef AF_VSOCK #define AF_VSOCK 40 #endif @@ -53,6 +15,10 @@ struct sockaddr_vm { #define SO_PEERGROUPS 59 #endif +#ifndef SO_PASSPIDFD +#define SO_PASSPIDFD 76 +#endif + #ifndef SO_PEERPIDFD #define SO_PEERPIDFD 77 #endif @@ -74,11 +40,14 @@ struct sockaddr_vm { #define SOL_SCTP 132 #endif -/* Not exposed yet. Defined in include/linux/socket.h */ #ifndef SCM_SECURITY #define SCM_SECURITY 0x03 #endif +#ifndef SCM_PIDFD +#define SCM_PIDFD 0x04 +#endif + /* netinet/in.h */ #ifndef IP_FREEBIND #define IP_FREEBIND 15 @@ -100,7 +69,9 @@ struct sockaddr_vm { #define IPV6_RECVFRAGSIZE 77 #endif -/* linux/sockios.h */ -#ifndef SIOCGSKNS -#define SIOCGSKNS 0x894C +/* The maximum number of fds that SCM_RIGHTS accepts. This is an internal kernel constant, but very much + * useful for userspace too. It's documented in unix(7) these days, hence should be fairly reliable to define + * here. */ +#ifndef SCM_MAX_FD +#define SCM_MAX_FD 253U #endif diff --git a/src/libnm-systemd-shared/src/basic/missing_syscall.h b/src/libnm-systemd-shared/src/basic/missing_syscall.h index 149c5b48..da6f9827 100644 --- a/src/libnm-systemd-shared/src/basic/missing_syscall.h +++ b/src/libnm-systemd-shared/src/basic/missing_syscall.h @@ -22,6 +22,7 @@ #include "macro.h" #include "missing_keyctl.h" +#include "missing_sched.h" #include "missing_stat.h" #include "missing_syscall_def.h" @@ -81,12 +82,7 @@ static inline int missing_ioprio_set(int which, int who, int ioprio) { #if !HAVE_MEMFD_CREATE static inline int missing_memfd_create(const char *name, unsigned int flags) { -# ifdef __NR_memfd_create return syscall(__NR_memfd_create, name, flags); -# else - errno = ENOSYS; - return -1; -# endif } # define memfd_create missing_memfd_create @@ -98,12 +94,7 @@ static inline int missing_memfd_create(const char *name, unsigned int flags) { #if !HAVE_GETRANDOM /* glibc says getrandom() returns ssize_t */ static inline ssize_t missing_getrandom(void *buffer, size_t count, unsigned flags) { -# ifdef __NR_getrandom return syscall(__NR_getrandom, buffer, count, flags); -# else - errno = ENOSYS; - return -1; -# endif } # define getrandom missing_getrandom @@ -150,12 +141,7 @@ static inline int missing_name_to_handle_at(int fd, const char *name, struct fil #if !HAVE_SETNS static inline int missing_setns(int fd, int nstype) { -# ifdef __NR_setns return syscall(__NR_setns, fd, nstype); -# else - errno = ENOSYS; - return -1; -# endif } # define setns missing_setns @@ -175,12 +161,7 @@ static inline pid_t raw_getpid(void) { #if !HAVE_RENAMEAT2 static inline int missing_renameat2(int oldfd, const char *oldname, int newfd, const char *newname, unsigned flags) { -# ifdef __NR_renameat2 return syscall(__NR_renameat2, oldfd, oldname, newfd, newname, flags); -# else - errno = ENOSYS; - return -1; -# endif } # define renameat2 missing_renameat2 @@ -190,12 +171,7 @@ static inline int missing_renameat2(int oldfd, const char *oldname, int newfd, c #if !HAVE_KCMP static inline int missing_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) { -# if defined __NR_kcmp && __NR_kcmp >= 0 return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2); -# else - errno = ENOSYS; - return -1; -# endif } # define kcmp missing_kcmp @@ -205,34 +181,19 @@ static inline int missing_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long i #if !HAVE_KEYCTL static inline long missing_keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) { -# if defined __NR_keyctl && __NR_keyctl >= 0 return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5); -# else - errno = ENOSYS; - return -1; -# endif # define keyctl missing_keyctl } static inline key_serial_t missing_add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid) { -# if defined __NR_add_key && __NR_add_key >= 0 return syscall(__NR_add_key, type, description, payload, plen, ringid); -# else - errno = ENOSYS; - return -1; -# endif # define add_key missing_add_key } static inline key_serial_t missing_request_key(const char *type, const char *description, const char * callout_info, key_serial_t destringid) { -# if defined __NR_request_key && __NR_request_key >= 0 return syscall(__NR_request_key, type, description, callout_info, destringid); -# else - errno = ENOSYS; - return -1; -# endif # define request_key missing_request_key } @@ -344,12 +305,7 @@ static inline long missing_get_mempolicy(int *mode, unsigned long *nodemask, #if !HAVE_PIDFD_SEND_SIGNAL static inline int missing_pidfd_send_signal(int fd, int sig, siginfo_t *info, unsigned flags) { -# ifdef __NR_pidfd_send_signal return syscall(__NR_pidfd_send_signal, fd, sig, info, flags); -# else - errno = ENOSYS; - return -1; -# endif } # define pidfd_send_signal missing_pidfd_send_signal @@ -357,12 +313,7 @@ static inline int missing_pidfd_send_signal(int fd, int sig, siginfo_t *info, un #if !HAVE_PIDFD_OPEN static inline int missing_pidfd_open(pid_t pid, unsigned flags) { -# ifdef __NR_pidfd_open return syscall(__NR_pidfd_open, pid, flags); -# else - errno = ENOSYS; - return -1; -# endif } # define pidfd_open missing_pidfd_open @@ -671,6 +622,17 @@ static inline ssize_t missing_getdents64(int fd, void *buffer, size_t length) { # define getdents64 missing_getdents64 #endif + +/* ======================================================================= */ + +#if !HAVE_SCHED_SETATTR + +static inline ssize_t missing_sched_setattr(pid_t pid, struct sched_attr *attr, unsigned int flags) { + return syscall(__NR_sched_setattr, pid, attr, flags); +} + +# define sched_setattr missing_sched_setattr +#endif #endif /* NM_IGNORED */ /* ======================================================================= */ @@ -686,3 +648,21 @@ int __clone2(int (*fn)(void *), void *stack_base, size_t stack_size, int flags, * at build time) and just define it. Once the kernel drops ia64 support, we can drop this too. */ #define HAVE_CLONE 1 #endif + +/* ======================================================================= */ + +#if 0 /* NM_IGNORED */ +#if !HAVE_QUOTACTL_FD + +static inline int missing_quotactl_fd(int fd, int cmd, int id, void *addr) { +#if defined __NR_quotactl_fd + return syscall(__NR_quotactl_fd, fd, cmd, id, addr); +#else + errno = ENOSYS; + return -1; +#endif +} + +# define quotactl_fd missing_quotactl_fd +#endif +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/missing_threads.h b/src/libnm-systemd-shared/src/basic/missing_threads.h index fb3b7224..c7da1dbd 100644 --- a/src/libnm-systemd-shared/src/basic/missing_threads.h +++ b/src/libnm-systemd-shared/src/basic/missing_threads.h @@ -5,9 +5,7 @@ #if HAVE_THREADS_H # include <threads.h> #elif !(defined(thread_local)) -/* Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__ - * see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769 */ -# if __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16)) +# ifndef __STDC_NO_THREADS__ # define thread_local _Thread_local # else # define thread_local __thread diff --git a/src/libnm-systemd-shared/src/basic/missing_type.h b/src/libnm-systemd-shared/src/basic/missing_type.h index f6233090..1d17705c 100644 --- a/src/libnm-systemd-shared/src/basic/missing_type.h +++ b/src/libnm-systemd-shared/src/basic/missing_type.h @@ -4,9 +4,9 @@ #include <uchar.h> #if !HAVE_CHAR32_T -#define char32_t uint32_t +# define char32_t uint32_t #endif #if !HAVE_CHAR16_T -#define char16_t uint16_t +# define char16_t uint16_t #endif diff --git a/src/libnm-systemd-shared/src/basic/missing_wait.h b/src/libnm-systemd-shared/src/basic/missing_wait.h new file mode 100644 index 00000000..3965b5bd --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/missing_wait.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include <sys/wait.h> + +#include "macro.h" + +#ifndef P_PIDFD +# define P_PIDFD 3 +#else +assert_cc(P_PIDFD == 3); +#endif diff --git a/src/libnm-systemd-shared/src/basic/namespace-util.h b/src/libnm-systemd-shared/src/basic/namespace-util.h index 34cbec3f..3d40a515 100644 --- a/src/libnm-systemd-shared/src/basic/namespace-util.h +++ b/src/libnm-systemd-shared/src/basic/namespace-util.h @@ -3,6 +3,8 @@ #include <sys/types.h> +#include "pidref.h" + typedef enum NamespaceType { NAMESPACE_CGROUP, NAMESPACE_IPC, @@ -19,9 +21,23 @@ typedef enum NamespaceType { extern const struct namespace_info { const char *proc_name; const char *proc_path; - unsigned int clone_flag; + unsigned long clone_flag; + unsigned long pidfd_get_ns_ioctl_cmd; + ino_t root_inode; } namespace_info[_NAMESPACE_TYPE_MAX + 1]; +NamespaceType clone_flag_to_namespace_type(unsigned long clone_flag); + +int pidref_namespace_open_by_type(const PidRef *pidref, NamespaceType type); +int namespace_open_by_type(NamespaceType type); + +int pidref_namespace_open( + const PidRef *pidref, + int *ret_pidns_fd, + int *ret_mntns_fd, + int *ret_netns_fd, + int *ret_userns_fd, + int *ret_root_fd); int namespace_open( pid_t pid, int *ret_pidns_fd, @@ -29,11 +45,28 @@ int namespace_open( int *ret_netns_fd, int *ret_userns_fd, int *ret_root_fd); + int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd); -int fd_is_ns(int fd, unsigned long nsflag); +int fd_is_namespace(int fd, NamespaceType type); +int is_our_namespace(int fd, NamespaceType type); + +int namespace_is_init(NamespaceType type); + +int pidref_in_same_namespace(PidRef *pid1, PidRef *pid2, NamespaceType type); +static inline int in_same_namespace(pid_t pid1, pid_t pid2, NamespaceType type) { + assert(pid1 >= 0); + assert(pid2 >= 0); + return pidref_in_same_namespace(pid1 == 0 ? NULL : &PIDREF_MAKE_FROM_PID(pid1), + pid2 == 0 ? NULL : &PIDREF_MAKE_FROM_PID(pid2), + type); +} + +int namespace_get_leader(PidRef *pidref, NamespaceType type, PidRef *ret); int detach_mount_namespace(void); +int detach_mount_namespace_harder(uid_t target_uid, gid_t target_gid); +int detach_mount_namespace_userns(int userns_fd); static inline bool userns_shift_range_valid(uid_t shift, uid_t range) { /* Checks that the specified userns range makes sense, i.e. contains at least one UID, and the end @@ -50,8 +83,16 @@ static inline bool userns_shift_range_valid(uid_t shift, uid_t range) { return true; } +int parse_userns_uid_range(const char *s, uid_t *ret_uid_shift, uid_t *ret_uid_range); + +int userns_acquire_empty(void); int userns_acquire(const char *uid_map, const char *gid_map); -int netns_acquire(void); -int in_same_namespace(pid_t pid1, pid_t pid2, NamespaceType type); +int userns_enter_and_pin(int userns_fd, pid_t *ret_pid); -int parse_userns_uid_range(const char *s, uid_t *ret_uid_shift, uid_t *ret_uid_range); +int userns_get_base_uid(int userns_fd, uid_t *ret_uid, gid_t *ret_gid); + +int process_is_owned_by_uid(const PidRef *pidref, uid_t uid); + +int is_idmapping_supported(const char *path); + +int netns_acquire(void); diff --git a/src/libnm-systemd-shared/src/basic/parse-util.c b/src/libnm-systemd-shared/src/basic/parse-util.c index 34a5375f..bff09b74 100644 --- a/src/libnm-systemd-shared/src/basic/parse-util.c +++ b/src/libnm-systemd-shared/src/basic/parse-util.c @@ -4,6 +4,7 @@ #include <errno.h> #include <inttypes.h> +#include <linux/ipv6.h> #include <net/if.h> #include <stdio.h> #include <stdlib.h> @@ -640,7 +641,7 @@ int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) { s = *p; /* accept any number of digits, strtoull is limited to 19 */ - for (size_t i = 0; i < digits; i++,s++) { + for (size_t i = 0; i < digits; i++, s++) { if (!ascii_isdigit(*s)) { if (i == 0) return -EINVAL; @@ -721,22 +722,6 @@ int parse_ip_port_range(const char *s, uint16_t *low, uint16_t *high, bool allow return 0; } -int parse_ip_prefix_length(const char *s, int *ret) { - unsigned l; - int r; - - r = safe_atou(s, &l); - if (r < 0) - return r; - - if (l > 128) - return -ERANGE; - - *ret = (int) l; - - return 0; -} - int parse_oom_score_adjust(const char *s, int *ret) { int r, v; diff --git a/src/libnm-systemd-shared/src/basic/parse-util.h b/src/libnm-systemd-shared/src/basic/parse-util.h index c12988ef..a47c8c79 100644 --- a/src/libnm-systemd-shared/src/basic/parse-util.h +++ b/src/libnm-systemd-shared/src/basic/parse-util.h @@ -141,8 +141,6 @@ int parse_nice(const char *p, int *ret); int parse_ip_port(const char *s, uint16_t *ret); int parse_ip_port_range(const char *s, uint16_t *low, uint16_t *high, bool allow_zero); -int parse_ip_prefix_length(const char *s, int *ret); - int parse_oom_score_adjust(const char *s, int *ret); /* Implement floating point using fixed integers, to improve performance when diff --git a/src/libnm-systemd-shared/src/basic/path-util.c b/src/libnm-systemd-shared/src/basic/path-util.c index 0e0f53d9..1de055d5 100644 --- a/src/libnm-systemd-shared/src/basic/path-util.c +++ b/src/libnm-systemd-shared/src/basic/path-util.c @@ -54,6 +54,7 @@ char* path_make_absolute(const char *p, const char *prefix) { return path_join(prefix, p); } +#endif /* NM_IGNORED */ int safe_getcwd(char **ret) { _cleanup_free_ char *cwd = NULL; @@ -73,6 +74,7 @@ int safe_getcwd(char **ret) { return 0; } +#if 0 /* NM_IGNORED */ int path_make_absolute_cwd(const char *p, char **ret) { char *c; int r; @@ -221,8 +223,10 @@ int path_make_relative_parent(const char *from_child, const char *to, char **ret } #endif /* NM_IGNORED */ -char* path_startswith_strv(const char *p, char **set) { - STRV_FOREACH(s, set) { +char* path_startswith_strv(const char *p, char * const *strv) { + assert(p); + + STRV_FOREACH(s, strv) { char *t; t = path_startswith(p, *s); @@ -531,6 +535,20 @@ int path_compare_filename(const char *a, const char *b) { return strcmp(fa, fb); } +#if 0 /* NM_IGNORED */ +int path_equal_or_inode_same_full(const char *a, const char *b, int flags) { + /* Returns true if paths are of the same entry, false if not, <0 on error. */ + + if (path_equal(a, b)) + return 1; + + if (!a || !b) + return 0; + + return inode_same(a, b, flags); +} +#endif /* NM_IGNORED */ + char* path_extend_internal(char **x, ...) { size_t sz, old_sz; char *q, *nx; @@ -646,7 +664,7 @@ static int find_executable_impl(const char *name, const char *root, char **ret_f * /usr/bin/sleep when find_executables is called. Hence, this function should be invoked when * needed to avoid unforeseen regression or other complicated changes. */ if (root) { - /* prefix root to name in case full paths are not specified */ + /* prefix root to name in case full paths are not specified */ r = chase(name, root, CHASE_PREFIX_ROOT, &path_name, /* ret_fd= */ NULL); if (r < 0) return r; @@ -662,6 +680,8 @@ static int find_executable_impl(const char *name, const char *root, char **ret_f r = path_make_absolute_cwd(name, ret_filename); if (r < 0) return r; + + path_simplify(*ret_filename); } if (ret_fd) @@ -673,48 +693,49 @@ static int find_executable_impl(const char *name, const char *root, char **ret_f int find_executable_full( const char *name, const char *root, - char **exec_search_path, + char * const *exec_search_path, bool use_path_envvar, char **ret_filename, int *ret_fd) { int last_error = -ENOENT, r = 0; - const char *p = NULL; assert(name); if (is_path(name)) return find_executable_impl(name, root, ret_filename, ret_fd); - if (use_path_envvar) - /* Plain getenv, not secure_getenv, because we want to actually allow the user to pick the - * binary. */ - p = getenv("PATH"); - if (!p) - p = DEFAULT_PATH; - if (exec_search_path) { STRV_FOREACH(element, exec_search_path) { _cleanup_free_ char *full_path = NULL; - if (!path_is_absolute(*element)) + if (!path_is_absolute(*element)) { + log_debug("Exec search path '%s' isn't absolute, ignoring.", *element); continue; + } full_path = path_join(*element, name); if (!full_path) return -ENOMEM; r = find_executable_impl(full_path, root, ret_filename, ret_fd); - if (r < 0) { - if (r != -EACCES) - last_error = r; - continue; - } - return 0; + if (r >= 0) + return 0; + if (r != -EACCES) + last_error = r; } return last_error; } + const char *p = NULL; + + if (use_path_envvar) + /* Plain getenv, not secure_getenv, because we want to actually allow the user to pick the + * binary. */ + p = getenv("PATH"); + if (!p) + p = default_PATH(); + /* Resolve a single-component name to a full path */ for (;;) { _cleanup_free_ char *element = NULL; @@ -725,22 +746,20 @@ int find_executable_full( if (r == 0) break; - if (!path_is_absolute(element)) + if (!path_is_absolute(element)) { + log_debug("Exec search path '%s' isn't absolute, ignoring.", element); continue; + } if (!path_extend(&element, name)) return -ENOMEM; r = find_executable_impl(element, root, ret_filename, ret_fd); - if (r < 0) { - /* PATH entries which we don't have access to are ignored, as per tradition. */ - if (r != -EACCES) - last_error = r; - continue; - } - - /* Found it! */ - return 0; + if (r >= 0) /* Found it! */ + return 0; + /* PATH entries which we don't have access to are ignored, as per tradition. */ + if (r != -EACCES) + last_error = r; } return last_error; @@ -1102,7 +1121,6 @@ int path_extract_filename(const char *path, char **ret) { } int path_extract_directory(const char *path, char **ret) { - _cleanup_free_ char *a = NULL; const char *c, *next = NULL; int r; @@ -1126,14 +1144,10 @@ int path_extract_directory(const char *path, char **ret) { if (*path != '/') /* filename only */ return -EDESTADDRREQ; - a = strdup("/"); - if (!a) - return -ENOMEM; - *ret = TAKE_PTR(a); - return 0; + return strdup_to(ret, "/"); } - a = strndup(path, next - path); + _cleanup_free_ char *a = strndup(path, next - path); if (!a) return -ENOMEM; @@ -1347,6 +1361,20 @@ bool dot_or_dot_dot(const char *path) { } #if 0 /* NM_IGNORED */ +bool path_implies_directory(const char *path) { + + /* Sometimes, if we look at a path we already know it must refer to a directory, because it is + * suffixed with a slash, or its last component is "." or ".." */ + + if (!path) + return false; + + if (dot_or_dot_dot(path)) + return true; + + return ENDSWITH_SET(path, "/", "/.", "/.."); +} + bool empty_or_root(const char *path) { /* For operations relative to some root directory, returns true if the specified root directory is @@ -1358,7 +1386,9 @@ bool empty_or_root(const char *path) { return path_equal(path, "/"); } -bool path_strv_contains(char **l, const char *path) { +bool path_strv_contains(char * const *l, const char *path) { + assert(path); + STRV_FOREACH(i, l) if (path_equal(*i, path)) return true; @@ -1366,7 +1396,9 @@ bool path_strv_contains(char **l, const char *path) { return false; } -bool prefixed_path_strv_contains(char **l, const char *path) { +bool prefixed_path_strv_contains(char * const *l, const char *path) { + assert(path); + STRV_FOREACH(i, l) { const char *j = *i; @@ -1374,6 +1406,7 @@ bool prefixed_path_strv_contains(char **l, const char *path) { j++; if (*j == '+') j++; + if (path_equal(j, path)) return true; } @@ -1443,4 +1476,32 @@ int path_glob_can_match(const char *pattern, const char *prefix, char **ret) { *ret = NULL; return false; } + +const char* default_PATH(void) { +#if HAVE_SPLIT_BIN + static int split = -1; + int r; + + /* Check whether /usr/sbin is not a symlink and return the appropriate $PATH. + * On error fall back to the safe value with both directories as configured… */ + + if (split < 0) + STRV_FOREACH_PAIR(bin, sbin, STRV_MAKE("/usr/bin", "/usr/sbin", + "/usr/local/bin", "/usr/local/sbin")) { + r = inode_same(*bin, *sbin, AT_NO_AUTOMOUNT); + if (r > 0 || r == -ENOENT) + continue; + if (r < 0) + log_debug_errno(r, "Failed to compare \"%s\" and \"%s\", using compat $PATH: %m", + *bin, *sbin); + split = true; + break; + } + if (split < 0) + split = false; + if (split) + return DEFAULT_PATH_WITH_SBIN; +#endif + return DEFAULT_PATH_WITHOUT_SBIN; +} #endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/path-util.h b/src/libnm-systemd-shared/src/basic/path-util.h index 5bb51ff5..9b13d958 100644 --- a/src/libnm-systemd-shared/src/basic/path-util.h +++ b/src/libnm-systemd-shared/src/basic/path-util.h @@ -12,27 +12,26 @@ #include "time-util.h" #if 0 /* NM_IGNORED */ -#define PATH_SPLIT_SBIN_BIN(x) x "sbin:" x "bin" -#define PATH_SPLIT_SBIN_BIN_NULSTR(x) x "sbin\0" x "bin\0" +#define PATH_SPLIT_BIN(x) x "sbin:" x "bin" +#define PATH_SPLIT_BIN_NULSTR(x) x "sbin\0" x "bin\0" -#define PATH_NORMAL_SBIN_BIN(x) x "bin" -#define PATH_NORMAL_SBIN_BIN_NULSTR(x) x "bin\0" +#define PATH_MERGED_BIN(x) x "bin" +#define PATH_MERGED_BIN_NULSTR(x) x "bin\0" -#if HAVE_SPLIT_BIN -# define PATH_SBIN_BIN(x) PATH_SPLIT_SBIN_BIN(x) -# define PATH_SBIN_BIN_NULSTR(x) PATH_SPLIT_SBIN_BIN_NULSTR(x) -#else -# define PATH_SBIN_BIN(x) PATH_NORMAL_SBIN_BIN(x) -# define PATH_SBIN_BIN_NULSTR(x) PATH_NORMAL_SBIN_BIN_NULSTR(x) -#endif +#define DEFAULT_PATH_WITH_SBIN PATH_SPLIT_BIN("/usr/local/") ":" PATH_SPLIT_BIN("/usr/") +#define DEFAULT_PATH_WITHOUT_SBIN PATH_MERGED_BIN("/usr/local/") ":" PATH_MERGED_BIN("/usr/") + +#define DEFAULT_PATH_COMPAT PATH_SPLIT_BIN("/usr/local/") ":" PATH_SPLIT_BIN("/usr/") ":" PATH_SPLIT_BIN("/") -#define DEFAULT_PATH PATH_SBIN_BIN("/usr/local/") ":" PATH_SBIN_BIN("/usr/") -#define DEFAULT_PATH_NULSTR PATH_SBIN_BIN_NULSTR("/usr/local/") PATH_SBIN_BIN_NULSTR("/usr/") -#define DEFAULT_PATH_COMPAT PATH_SPLIT_SBIN_BIN("/usr/local/") ":" PATH_SPLIT_SBIN_BIN("/usr/") ":" PATH_SPLIT_SBIN_BIN("/") +const char* default_PATH(void); -#ifndef DEFAULT_USER_PATH -# define DEFAULT_USER_PATH DEFAULT_PATH +static inline const char* default_user_PATH(void) { +#ifdef DEFAULT_USER_PATH + return DEFAULT_USER_PATH; +#else + return default_PATH(); #endif +} #endif /* NM_IGNORED */ static inline bool is_path(const char *p) { @@ -70,14 +69,19 @@ static inline bool path_equal_filename(const char *a, const char *b) { return path_compare_filename(a, b) == 0; } +int path_equal_or_inode_same_full(const char *a, const char *b, int flags); static inline bool path_equal_or_inode_same(const char *a, const char *b, int flags) { - return path_equal(a, b) || inode_same(a, b, flags) > 0; + return path_equal_or_inode_same_full(a, b, flags) > 0; } char* path_extend_internal(char **x, ...); #define path_extend(x, ...) path_extend_internal(x, __VA_ARGS__, POINTER_MAX) #define path_join(...) path_extend_internal(NULL, __VA_ARGS__, POINTER_MAX) +static inline char* skip_leading_slash(const char *p) { + return skip_leading_chars(p, "/"); +} + typedef enum PathSimplifyFlags { PATH_SIMPLIFY_KEEP_TRAILING_SLASH = 1 << 0, } PathSimplifyFlags; @@ -103,21 +107,23 @@ static inline int path_simplify_alloc(const char *path, char **ret) { return 0; } -static inline bool path_equal_ptr(const char *a, const char *b) { - return !!a == !!b && (!a || path_equal(a, b)); -} - /* Note: the search terminates on the first NULL item. */ #define PATH_IN_SET(p, ...) path_strv_contains(STRV_MAKE(__VA_ARGS__), p) -char* path_startswith_strv(const char *p, char **set); +char* path_startswith_strv(const char *p, char * const *strv); #define PATH_STARTSWITH_SET(p, ...) path_startswith_strv(p, STRV_MAKE(__VA_ARGS__)) int path_strv_make_absolute_cwd(char **l); char** path_strv_resolve(char **l, const char *root); char** path_strv_resolve_uniq(char **l, const char *root); -int find_executable_full(const char *name, const char *root, char **exec_search_path, bool use_path_envvar, char **ret_filename, int *ret_fd); +int find_executable_full( + const char *name, + const char *root, + char * const *exec_search_path, + bool use_path_envvar, + char **ret_filename, + int *ret_fd); static inline int find_executable(const char *name, char **ret_filename) { return find_executable_full(name, /* root= */ NULL, NULL, true, ret_filename, NULL); } @@ -203,7 +209,9 @@ bool valid_device_allow_pattern(const char *path); bool dot_or_dot_dot(const char *path); -static inline const char *skip_dev_prefix(const char *p) { +bool path_implies_directory(const char *path); + +static inline const char* skip_dev_prefix(const char *p) { const char *e; /* Drop any /dev prefix if there is any */ @@ -218,7 +226,7 @@ static inline const char* empty_to_root(const char *path) { return isempty(path) ? "/" : path; } -bool path_strv_contains(char **l, const char *path); -bool prefixed_path_strv_contains(char **l, const char *path); +bool path_strv_contains(char * const *l, const char *path); +bool prefixed_path_strv_contains(char * const *l, const char *path); int path_glob_can_match(const char *pattern, const char *prefix, char **ret); diff --git a/src/libnm-systemd-shared/src/basic/pidfd-util.c b/src/libnm-systemd-shared/src/basic/pidfd-util.c new file mode 100644 index 00000000..d6bd5517 --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/pidfd-util.c @@ -0,0 +1,279 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include <sys/ioctl.h> +#include <unistd.h> + +#include "errno-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "macro.h" +#include "memory-util.h" +#include "missing_magic.h" +#include "missing_threads.h" +#include "parse-util.h" +#include "path-util.h" +#include "pidfd-util.h" +#include "process-util.h" +#include "stat-util.h" +#include "string-util.h" + +static int have_pidfs = -1; + +static int pidfd_check_pidfs(int pid_fd) { + + /* NB: the passed fd *must* be acquired via pidfd_open(), i.e. must be a true pidfd! */ + + if (have_pidfs >= 0) + return have_pidfs; + + return (have_pidfs = fd_is_fs_type(pid_fd, PID_FS_MAGIC)); +} + +int pidfd_get_namespace(int fd, unsigned long ns_type_cmd) { + static bool cached_supported = true; + + /* Obtain the namespace fd from pidfd directly through ioctl(PIDFD_GET_*_NAMESPACE). + * + * Returns -EOPNOTSUPP if ioctl on pidfds are not supported, -ENOPKG if the requested namespace + * is disabled in kernel. (The errno used are different from what kernel returns via ioctl(), + * see below) */ + + assert(fd >= 0); + + /* If we know ahead of time that pidfs is unavailable, shortcut things. But otherwise we don't + * call pidfd_check_pidfs() here, which is kinda extraneous and our own cache is required + * anyways (pidfs is introduced in kernel 6.9 while ioctl support there is added in 6.11). */ + if (have_pidfs == 0 || !cached_supported) + return -EOPNOTSUPP; + + int nsfd = ioctl(fd, ns_type_cmd); + if (nsfd < 0) { + /* Kernel returns EOPNOTSUPP if the ns type in question is disabled. Hence we need to look + * at precise errno instead of generic ERRNO_IS_(IOCTL_)NOT_SUPPORTED. */ + if (IN_SET(errno, ENOTTY, EINVAL)) { + cached_supported = false; + return -EOPNOTSUPP; + } + if (errno == EOPNOTSUPP) /* Translate to something more recognizable */ + return -ENOPKG; + + return -errno; + } + + return nsfd; +} + +#if 0 /* NM_IGNORED */ +static int pidfd_get_info(int fd, struct pidfd_info *info) { + static bool cached_supported = true; + + assert(fd >= 0); + assert(info); + + if (have_pidfs == 0 || !cached_supported) + return -EOPNOTSUPP; + + if (ioctl(fd, PIDFD_GET_INFO, info) < 0) { + if (ERRNO_IS_IOCTL_NOT_SUPPORTED(errno)) { + cached_supported = false; + return -EOPNOTSUPP; + } + + return -errno; + } + + return 0; +} + +static int pidfd_get_pid_fdinfo(int fd, pid_t *ret) { + char path[STRLEN("/proc/self/fdinfo/") + DECIMAL_STR_MAX(int)]; + _cleanup_free_ char *fdinfo = NULL; + int r; + + assert(fd >= 0); + + xsprintf(path, "/proc/self/fdinfo/%i", fd); + + r = read_full_virtual_file(path, &fdinfo, NULL); + if (r == -ENOENT) + return proc_fd_enoent_errno(); + if (r < 0) + return r; + + char *p = find_line_startswith(fdinfo, "Pid:"); + if (!p) + return -ENOTTY; /* not a pidfd? */ + + p = skip_leading_chars(p, /* bad = */ NULL); + p[strcspn(p, WHITESPACE)] = 0; + + if (streq(p, "0")) + return -EREMOTE; /* PID is in foreign PID namespace? */ + if (streq(p, "-1")) + return -ESRCH; /* refers to reaped process? */ + + return parse_pid(p, ret); +} + +static int pidfd_get_pid_ioctl(int fd, pid_t *ret) { + struct pidfd_info info = { .mask = PIDFD_INFO_PID }; + int r; + + assert(fd >= 0); + + r = pidfd_get_info(fd, &info); + if (r < 0) + return r; + + assert(FLAGS_SET(info.mask, PIDFD_INFO_PID)); + + if (ret) + *ret = info.pid; + return 0; +} + +int pidfd_get_pid(int fd, pid_t *ret) { + int r; + + /* Converts a pidfd into a pid. We try ioctl(PIDFD_GET_INFO) (kernel 6.13+) first, + * /proc/self/fdinfo/ as fallback. Well known errors: + * + * -EBADF → fd invalid + * -ESRCH → fd valid, but process is already reaped + * + * pidfd_get_pid_fdinfo() might additionally fail for other reasons: + * + * -ENOSYS → /proc/ not mounted + * -ENOTTY → fd valid, but not a pidfd + * -EREMOTE → fd valid, but pid is in another namespace we cannot translate to the local one + * (when using PIDFD_GET_INFO this is indistinguishable from -ESRCH) + */ + + assert(fd >= 0); + + r = pidfd_get_pid_ioctl(fd, ret); + if (r != -EOPNOTSUPP) + return r; + + return pidfd_get_pid_fdinfo(fd, ret); +} + +int pidfd_verify_pid(int pidfd, pid_t pid) { + pid_t current_pid; + int r; + + assert(pidfd >= 0); + assert(pid > 0); + + r = pidfd_get_pid(pidfd, ¤t_pid); + if (r < 0) + return r; + + return current_pid != pid ? -ESRCH : 0; +} + +int pidfd_get_ppid(int fd, pid_t *ret) { + struct pidfd_info info = { .mask = PIDFD_INFO_PID }; + int r; + + assert(fd >= 0); + + r = pidfd_get_info(fd, &info); + if (r < 0) + return r; + + assert(FLAGS_SET(info.mask, PIDFD_INFO_PID)); + + if (info.ppid == 0) /* See comments in pid_get_ppid() */ + return -EADDRNOTAVAIL; + + if (ret) + *ret = info.ppid; + return 0; +} + +int pidfd_get_uid(int fd, uid_t *ret) { + struct pidfd_info info = { .mask = PIDFD_INFO_CREDS }; + int r; + + assert(fd >= 0); + + r = pidfd_get_info(fd, &info); + if (r < 0) + return r; + + assert(FLAGS_SET(info.mask, PIDFD_INFO_CREDS)); + + if (ret) + *ret = info.ruid; + return 0; +} + +int pidfd_get_cgroupid(int fd, uint64_t *ret) { + struct pidfd_info info = { .mask = PIDFD_INFO_CGROUPID }; + int r; + + assert(fd >= 0); + + r = pidfd_get_info(fd, &info); + if (r < 0) + return r; + + assert(FLAGS_SET(info.mask, PIDFD_INFO_CGROUPID)); + + if (ret) + *ret = info.cgroupid; + return 0; +} +#endif /* NM_IGNORED */ + +int pidfd_get_inode_id(int fd, uint64_t *ret) { + int r; + + assert(fd >= 0); + + r = pidfd_check_pidfs(fd); + if (r < 0) + return r; + if (r == 0) + return -EOPNOTSUPP; + + struct stat st; + if (fstat(fd, &st) < 0) + return -errno; + + if (ret) + *ret = (uint64_t) st.st_ino; + return 0; +} + +int pidfd_get_inode_id_self_cached(uint64_t *ret) { + static thread_local uint64_t cached = 0; + static thread_local pid_t initialized = 0; /* < 0: cached error; == 0: invalid; > 0: valid and pid that was current */ + int r; + + assert(ret); + + if (initialized == getpid_cached()) { + *ret = cached; + return 0; + } + if (initialized < 0) + return initialized; + + _cleanup_close_ int fd = pidfd_open(getpid_cached(), 0); + if (fd < 0) + return -errno; + + r = pidfd_get_inode_id(fd, &cached); + if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) + return (initialized = -EOPNOTSUPP); + if (r < 0) + return r; + + *ret = cached; + initialized = getpid_cached(); + return 0; +} diff --git a/src/libnm-systemd-shared/src/basic/pidfd-util.h b/src/libnm-systemd-shared/src/basic/pidfd-util.h new file mode 100644 index 00000000..c20de6df --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/pidfd-util.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include <stdint.h> +#include <sys/types.h> + +#include "missing_pidfd.h" +#include "missing_syscall.h" + +int pidfd_get_namespace(int fd, unsigned long ns_type_cmd); + +int pidfd_get_pid(int fd, pid_t *ret); +int pidfd_verify_pid(int pidfd, pid_t pid); + +int pidfd_get_ppid(int fd, pid_t *ret); +int pidfd_get_uid(int fd, uid_t *ret); +int pidfd_get_cgroupid(int fd, uint64_t *ret); + +int pidfd_get_inode_id(int fd, uint64_t *ret); + +int pidfd_get_inode_id_self_cached(uint64_t *ret); diff --git a/src/libnm-systemd-shared/src/basic/pidref.h b/src/libnm-systemd-shared/src/basic/pidref.h index c440c8b0..9e8a39ec 100644 --- a/src/libnm-systemd-shared/src/basic/pidref.h +++ b/src/libnm-systemd-shared/src/basic/pidref.h @@ -1,15 +1,50 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include "macro.h" - -/* An embeddable structure carrying a reference to a process. Supposed to be used when tracking processes continuously. */ -typedef struct PidRef { - pid_t pid; /* always valid */ - int fd; /* only valid if pidfd are available in the kernel, and we manage to get an fd */ -} PidRef; +typedef struct PidRef PidRef; -#define PIDREF_NULL (const PidRef) { .fd = -EBADF } +#include "macro.h" +#include "process-util.h" + +/* An embeddable structure carrying a reference to a process. Supposed to be used when tracking processes + * continuously. This combines a PID, a modern Linux pidfd and the 64bit inode number of the pidfd into one + * structure. Note that depending on kernel support the pidfd might not be initialized, and if it is + * initialized then fd_id might still not be initialized (because the concept was added to the kernel much + * later than pidfds themselves). + * + * There are three special states a PidRef can be in: + * + * 1. It can be *unset*. Use pidref_is_set() to detect this case. Most operations attempted on such a PidRef + * will fail with -ESRCH. Use PIDREF_NULL for initializing a PidRef in this state. + * + * 2. It can be marked as *automatic*. This is a special state indicating that a process reference is + * supposed to be derived automatically from the current context. This is used by the Varlink/JSON + * dispatcher as indication that a PidRef shall be derived from the connection peer, but might be + * otherwise used too. When marked *automatic* the PidRef will also be considered *unset*, hence most + * operations will fail with -ESRCH, as above. + * + * 3. It can be marked as *remote*. This is useful when deserializing a PidRef structure from an IPC message + * or similar, and it has been determined that the given PID definitely doesn't refer to a local + * process. In this case the PidRef logic will refrain from trying to acquire a pidfd for the + * process. Moreover, most operations will fail with -EREMOTE. Only PidRef structures that are not marked + * *unset* can be marked *remote*. + */ +struct PidRef { + pid_t pid; /* > 0 if the PidRef is set, otherwise set to PID_AUTOMATIC if automatic mode is + * desired, or 0 otherwise. */ + int fd; /* only valid if pidfd are available in the kernel, and we manage to get an fd. If we + * know that the PID is not from the local machine we set this to -EREMOTE, otherwise + * we use -EBADF as indicator the fd is invalid. */ + uint64_t fd_id; /* the inode number of pidfd. only useful in kernel 6.9+ where pidfds live in + their own pidfs and each process comes with a unique inode number */ +}; + +#define PIDREF_NULL (PidRef) { .fd = -EBADF } + +/* A special pidref value that we are using when a PID shall be automatically acquired from some surrounding + * context, for example connection peer. Much like PIDREF_NULL it will be considered unset by + * pidref_is_set().*/ +#define PIDREF_AUTOMATIC (const PidRef) { .pid = PID_AUTOMATIC, .fd = -EBADF } /* Turns a pid_t into a PidRef structure on-the-fly *without* acquiring a pidfd for it. (As opposed to * pidref_set_pid() which does so *with* acquiring one, see below) */ @@ -19,18 +54,17 @@ static inline bool pidref_is_set(const PidRef *pidref) { return pidref && pidref->pid > 0; } -static inline bool pidref_equal(const PidRef *a, const PidRef *b) { +bool pidref_is_automatic(const PidRef *pidref); - if (pidref_is_set(a)) { - if (!pidref_is_set(b)) - return false; - - return a->pid == b->pid; - } - - return !pidref_is_set(b); +static inline bool pidref_is_remote(const PidRef *pidref) { + /* If the fd is set to -EREMOTE we assume PidRef does not refer to a local PID, but on another + * machine (and we just got the PidRef initialized due to deserialization of some RPC message) */ + return pidref_is_set(pidref) && pidref->fd == -EREMOTE; } +int pidref_acquire_pidfd_id(PidRef *pidref); +bool pidref_equal(PidRef *a, PidRef *b); + /* This turns a pid_t into a PidRef structure, and acquires a pidfd for it, if possible. (As opposed to * PIDREF_MAKE_FROM_PID() above, which does not acquire a pidfd.) */ int pidref_set_pid(PidRef *pidref, pid_t pid); @@ -43,13 +77,13 @@ static inline int pidref_set_self(PidRef *pidref) { return pidref_set_pid(pidref, 0); } -bool pidref_is_self(const PidRef *pidref); +bool pidref_is_self(PidRef *pidref); void pidref_done(PidRef *pidref); -PidRef *pidref_free(PidRef *pidref); +PidRef* pidref_free(PidRef *pidref); DEFINE_TRIVIAL_CLEANUP_FUNC(PidRef*, pidref_free); -int pidref_copy(const PidRef *pidref, PidRef *dest); +int pidref_copy(const PidRef *pidref, PidRef *ret); int pidref_dup(const PidRef *pidref, PidRef **ret); int pidref_new_from_pid(pid_t pid, PidRef **ret); @@ -58,8 +92,8 @@ int pidref_kill(const PidRef *pidref, int sig); int pidref_kill_and_sigcont(const PidRef *pidref, int sig); int pidref_sigqueue(const PidRef *pidref, int sig, int value); -int pidref_wait(const PidRef *pidref, siginfo_t *siginfo, int options); -int pidref_wait_for_terminate(const PidRef *pidref, siginfo_t *ret); +int pidref_wait(PidRef *pidref, siginfo_t *siginfo, int options); +int pidref_wait_for_terminate(PidRef *pidref, siginfo_t *ret); static inline void pidref_done_sigkill_wait(PidRef *pidref) { if (!pidref_is_set(pidref)) diff --git a/src/libnm-systemd-shared/src/basic/prioq.c b/src/libnm-systemd-shared/src/basic/prioq.c index b05b08da..c36d0ddd 100644 --- a/src/libnm-systemd-shared/src/basic/prioq.c +++ b/src/libnm-systemd-shared/src/basic/prioq.c @@ -26,8 +26,7 @@ struct prioq_item { struct Prioq { compare_func_t compare_func; - unsigned n_items, n_allocated; - + unsigned n_items; struct prioq_item *items; }; @@ -144,28 +143,18 @@ static unsigned shuffle_down(Prioq *q, unsigned idx) { } int prioq_put(Prioq *q, void *data, unsigned *idx) { - struct prioq_item *i; unsigned k; assert(q); - if (q->n_items >= q->n_allocated) { - unsigned n; - struct prioq_item *j; - - n = MAX((q->n_items+1) * 2, 16u); - j = reallocarray(q->items, n, sizeof(struct prioq_item)); - if (!j) - return -ENOMEM; - - q->items = j; - q->n_allocated = n; - } + if (!GREEDY_REALLOC(q->items, MAX(q->n_items + 1, 16u))) + return -ENOMEM; k = q->n_items++; - i = q->items + k; - i->data = data; - i->idx = idx; + q->items[k] = (struct prioq_item) { + .data = data, + .idx = idx, + }; if (idx) *idx = k; diff --git a/src/libnm-systemd-shared/src/basic/process-util.c b/src/libnm-systemd-shared/src/basic/process-util.c index 5dd9003d..85187562 100644 --- a/src/libnm-systemd-shared/src/basic/process-util.c +++ b/src/libnm-systemd-shared/src/basic/process-util.c @@ -27,6 +27,7 @@ #include "alloc-util.h" #include "architecture.h" #include "argv-util.h" +#include "cgroup-util.h" #include "dirent-util.h" #include "env-file.h" #include "env-util.h" @@ -36,6 +37,7 @@ #include "fileio.h" #include "fs-util.h" #include "hostname-util.h" +#include "io-util.h" #include "locale-util.h" #include "log.h" #include "macro.h" @@ -48,6 +50,7 @@ #include "nulstr-util.h" #include "parse-util.h" #include "path-util.h" +#include "pidfd-util.h" #include "process-util.h" #include "raw-clone.h" #include "rlimit-util.h" @@ -57,6 +60,7 @@ #include "string-table.h" #include "string-util.h" #include "terminal-util.h" +#include "time-util.h" #include "user-util.h" #include "utf8.h" @@ -103,8 +107,8 @@ int pid_get_comm(pid_t pid, char **ret) { _cleanup_free_ char *escaped = NULL, *comm = NULL; int r; - assert(ret); assert(pid >= 0); + assert(ret); if (pid == 0 || pid == getpid_cached()) { comm = new0(char, TASK_COMM_LEN + 1); /* Must fit in 16 byte according to prctl(2) */ @@ -144,6 +148,9 @@ int pidref_get_comm(const PidRef *pid, char **ret) { if (!pidref_is_set(pid)) return -ESRCH; + if (pidref_is_remote(pid)) + return -EREMOTE; + r = pid_get_comm(pid->pid, &comm); if (r < 0) return r; @@ -290,6 +297,9 @@ int pidref_get_cmdline(const PidRef *pid, size_t max_columns, ProcessCmdlineFlag if (!pidref_is_set(pid)) return -ESRCH; + if (pidref_is_remote(pid)) + return -EREMOTE; + r = pid_get_cmdline(pid->pid, max_columns, flags, &s); if (r < 0) return r; @@ -332,6 +342,9 @@ int pidref_get_cmdline_strv(const PidRef *pid, ProcessCmdlineFlags flags, char * if (!pidref_is_set(pid)) return -ESRCH; + if (pidref_is_remote(pid)) + return -EREMOTE; + r = pid_get_cmdline_strv(pid->pid, flags, &args); if (r < 0) return r; @@ -387,33 +400,6 @@ int container_get_leader(const char *machine, pid_t *pid) { return 0; } -int namespace_get_leader(pid_t pid, NamespaceType type, pid_t *ret) { - int r; - - assert(ret); - - for (;;) { - pid_t ppid; - - r = get_process_ppid(pid, &ppid); - if (r < 0) - return r; - - r = in_same_namespace(pid, ppid, type); - if (r < 0) - return r; - if (r == 0) { - /* If the parent and the child are not in the same - * namespace, then the child is the leader we are - * looking for. */ - *ret = pid; - return 0; - } - - pid = ppid; - } -} - int pid_is_kernel_thread(pid_t pid) { _cleanup_free_ char *line = NULL; unsigned long long flags; @@ -478,6 +464,9 @@ int pidref_is_kernel_thread(const PidRef *pid) { if (!pidref_is_set(pid)) return -ESRCH; + if (pidref_is_remote(pid)) + return -EREMOTE; + result = pid_is_kernel_thread(pid->pid); if (result < 0) return result; @@ -489,22 +478,6 @@ int pidref_is_kernel_thread(const PidRef *pid) { return result; } -int get_process_capeff(pid_t pid, char **ret) { - const char *p; - int r; - - assert(pid >= 0); - assert(ret); - - p = procfs_file_alloca(pid, "status"); - - r = get_proc_field(p, "CapEff", WHITESPACE, ret); - if (r == -ENOENT) - return -ESRCH; - - return r; -} - static int get_process_link_contents(pid_t pid, const char *proc_file, char **ret) { const char *p; int r; @@ -589,12 +562,21 @@ int pid_get_uid(pid_t pid, uid_t *ret) { } int pidref_get_uid(const PidRef *pid, uid_t *ret) { - uid_t uid; int r; if (!pidref_is_set(pid)) return -ESRCH; + if (pidref_is_remote(pid)) + return -EREMOTE; + + if (pid->fd >= 0) { + r = pidfd_get_uid(pid->fd, ret); + if (!ERRNO_IS_NEG_NOT_SUPPORTED(r)) + return r; + } + + uid_t uid; r = pid_get_uid(pid->pid, &uid); if (r < 0) return r; @@ -680,7 +662,7 @@ int get_process_environ(pid_t pid, char **ret) { return 0; } -int get_process_ppid(pid_t pid, pid_t *ret) { +int pid_get_ppid(pid_t pid, pid_t *ret) { _cleanup_free_ char *line = NULL; unsigned long ppid; const char *p; @@ -688,15 +670,17 @@ int get_process_ppid(pid_t pid, pid_t *ret) { assert(pid >= 0); - if (pid == 0 || pid == getpid_cached()) { + if (pid == 0) + pid = getpid_cached(); + if (pid == 1) /* PID 1 has no parent, shortcut this case */ + return -EADDRNOTAVAIL; + + if (pid == getpid_cached()) { if (ret) *ret = getppid(); return 0; } - if (pid == 1) /* PID 1 has no parent, shortcut this case */ - return -EADDRNOTAVAIL; - p = procfs_file_alloca(pid, "stat"); r = read_one_line_file(p, &line); if (r == -ENOENT) @@ -710,7 +694,6 @@ int get_process_ppid(pid_t pid, pid_t *ret) { p = strrchr(line, ')'); if (!p) return -EIO; - p++; if (sscanf(p, " " @@ -719,9 +702,9 @@ int get_process_ppid(pid_t pid, pid_t *ret) { &ppid) != 1) return -EIO; - /* If ppid is zero the process has no parent. Which might be the case for PID 1 but also for - * processes originating in other namespaces that are inserted into a pidns. Return a recognizable - * error in this case. */ + /* If ppid is zero the process has no parent. Which might be the case for PID 1 (caught above) + * but also for processes originating in other namespaces that are inserted into a pidns. + * Return a recognizable error in this case. */ if (ppid == 0) return -EADDRNOTAVAIL; @@ -734,7 +717,74 @@ int get_process_ppid(pid_t pid, pid_t *ret) { return 0; } -int pid_get_start_time(pid_t pid, uint64_t *ret) { +int pidref_get_ppid(const PidRef *pidref, pid_t *ret) { + int r; + + if (!pidref_is_set(pidref)) + return -ESRCH; + + if (pidref_is_remote(pidref)) + return -EREMOTE; + + if (pidref->fd >= 0) { + r = pidfd_get_ppid(pidref->fd, ret); + if (!ERRNO_IS_NEG_NOT_SUPPORTED(r)) + return r; + } + + pid_t ppid; + r = pid_get_ppid(pidref->pid, ret ? &ppid : NULL); + if (r < 0) + return r; + + r = pidref_verify(pidref); + if (r < 0) + return r; + + if (ret) + *ret = ppid; + return 0; +} + +int pidref_get_ppid_as_pidref(const PidRef *pidref, PidRef *ret) { + pid_t ppid; + int r; + + assert(ret); + + r = pidref_get_ppid(pidref, &ppid); + if (r < 0) + return r; + + for (unsigned attempt = 0; attempt < 16; attempt++) { + _cleanup_(pidref_done) PidRef parent = PIDREF_NULL; + + r = pidref_set_pid(&parent, ppid); + if (r < 0) + return r; + + /* If we have a pidfd of the original PID, let's verify that the process we acquired really + * is the parent still */ + if (pidref->fd >= 0) { + r = pidref_get_ppid(pidref, &ppid); + if (r < 0) + return r; + + /* Did the PPID change since we queried it? if so we might have pinned the wrong + * process, if its PID got reused by now. Let's try again */ + if (parent.pid != ppid) + continue; + } + + *ret = TAKE_PIDREF(parent); + return 0; + } + + /* Give up after 16 tries */ + return -ENOTRECOVERABLE; +} + +int pid_get_start_time(pid_t pid, usec_t *ret) { _cleanup_free_ char *line = NULL; const char *p; int r; @@ -754,13 +804,12 @@ int pid_get_start_time(pid_t pid, uint64_t *ret) { p = strrchr(line, ')'); if (!p) return -EIO; - p++; unsigned long llu; if (sscanf(p, " " - "%*c " /* state */ + "%*c " /* state */ "%*u " /* ppid */ "%*u " /* pgrp */ "%*u " /* session */ @@ -784,18 +833,21 @@ int pid_get_start_time(pid_t pid, uint64_t *ret) { return -EIO; if (ret) - *ret = llu; + *ret = jiffies_to_usec(llu); /* CLOCK_BOOTTIME */ return 0; } -int pidref_get_start_time(const PidRef *pid, uint64_t *ret) { - uint64_t t; +int pidref_get_start_time(const PidRef *pid, usec_t *ret) { + usec_t t; int r; if (!pidref_is_set(pid)) return -ESRCH; + if (pidref_is_remote(pid)) + return -EREMOTE; + r = pid_get_start_time(pid->pid, ret ? &t : NULL); if (r < 0) return r; @@ -1026,7 +1078,6 @@ int kill_and_sigcont(pid_t pid, int sig) { int getenv_for_pid(pid_t pid, const char *field, char **ret) { _cleanup_fclose_ FILE *f = NULL; - char *value = NULL; const char *path; size_t sum = 0; int r; @@ -1035,22 +1086,8 @@ int getenv_for_pid(pid_t pid, const char *field, char **ret) { assert(field); assert(ret); - if (pid == 0 || pid == getpid_cached()) { - const char *e; - - e = getenv(field); - if (!e) { - *ret = NULL; - return 0; - } - - value = strdup(e); - if (!value) - return -ENOMEM; - - *ret = value; - return 1; - } + if (pid == 0 || pid == getpid_cached()) + return strdup_to_full(ret, getenv(field)); if (!pid_is_valid(pid)) return -EINVAL; @@ -1079,78 +1116,55 @@ int getenv_for_pid(pid_t pid, const char *field, char **ret) { sum += r; match = startswith(line, field); - if (match && *match == '=') { - value = strdup(match + 1); - if (!value) - return -ENOMEM; - - *ret = value; - return 1; - } + if (match && *match == '=') + return strdup_to_full(ret, match + 1); } *ret = NULL; return 0; } -int pid_is_my_child(pid_t pid) { - pid_t ppid; +int pidref_is_my_child(PidRef *pid) { int r; - if (pid < 0) + if (!pidref_is_set(pid)) return -ESRCH; - if (pid <= 1) + if (pidref_is_remote(pid)) + return -EREMOTE; + + if (pid->pid == 1 || pidref_is_self(pid)) return false; - r = get_process_ppid(pid, &ppid); + pid_t ppid; + r = pidref_get_ppid(pid, &ppid); + if (r == -EADDRNOTAVAIL) /* if this process is outside of our pidns, it is definitely not our child */ + return false; if (r < 0) return r; return ppid == getpid_cached(); } -int pidref_is_my_child(const PidRef *pid) { - int r, result; - - if (!pidref_is_set(pid)) - return -ESRCH; - - result = pid_is_my_child(pid->pid); - if (result < 0) - return result; - - r = pidref_verify(pid); - if (r < 0) - return r; - - return result; -} - -int pid_is_unwaited(pid_t pid) { - /* Checks whether a PID is still valid at all, including a zombie */ - - if (pid < 0) - return -ESRCH; - - if (pid <= 1) /* If we or PID 1 would be dead and have been waited for, this code would not be running */ - return true; - - if (pid == getpid_cached()) - return true; +int pid_is_my_child(pid_t pid) { - if (kill(pid, 0) >= 0) - return true; + if (pid == 0) + return false; - return errno != ESRCH; + return pidref_is_my_child(&PIDREF_MAKE_FROM_PID(pid)); } -int pidref_is_unwaited(const PidRef *pid) { +int pidref_is_unwaited(PidRef *pid) { int r; + /* Checks whether a PID is still valid at all, including a zombie */ + if (!pidref_is_set(pid)) return -ESRCH; + if (pidref_is_remote(pid)) + return -EREMOTE; + if (pid->pid == 1 || pidref_is_self(pid)) return true; @@ -1163,6 +1177,14 @@ int pidref_is_unwaited(const PidRef *pid) { return true; } +int pid_is_unwaited(pid_t pid) { + + if (pid == 0) + return true; + + return pidref_is_unwaited(&PIDREF_MAKE_FROM_PID(pid)); +} + int pid_is_alive(pid_t pid) { int r; @@ -1192,6 +1214,9 @@ int pidref_is_alive(const PidRef *pidref) { if (!pidref_is_set(pidref)) return -ESRCH; + if (pidref_is_remote(pidref)) + return -EREMOTE; + result = pid_is_alive(pidref->pid); if (result < 0) { assert(result != -ESRCH); @@ -1207,28 +1232,63 @@ int pidref_is_alive(const PidRef *pidref) { return result; } -int pid_from_same_root_fs(pid_t pid) { - const char *root; +int pidref_from_same_root_fs(PidRef *a, PidRef *b) { + _cleanup_(pidref_done) PidRef self = PIDREF_NULL; + int r; - if (pid < 0) + /* Checks if the two specified processes have the same root fs. Either can be specified as NULL in + * which case we'll check against ourselves. */ + + if (!a || !b) { + r = pidref_set_self(&self); + if (r < 0) + return r; + if (!a) + a = &self; + if (!b) + b = &self; + } + + if (!pidref_is_set(a) || !pidref_is_set(b)) + return -ESRCH; + + /* If one of the two processes have the same root they cannot have the same root fs, but if both of + * them do we don't know */ + if (pidref_is_remote(a) && pidref_is_remote(b)) + return -EREMOTE; + if (pidref_is_remote(a) || pidref_is_remote(b)) return false; - if (pid == 0 || pid == getpid_cached()) + if (pidref_equal(a, b)) return true; - root = procfs_file_alloca(pid, "root"); + const char *roota = procfs_file_alloca(a->pid, "root"); + const char *rootb = procfs_file_alloca(b->pid, "root"); + + int result = inode_same(roota, rootb, 0); + if (result == -ENOENT) + return proc_mounted() == 0 ? -ENOSYS : -ESRCH; + if (result < 0) + return result; - return inode_same(root, "/proc/1/root", 0); + r = pidref_verify(a); + if (r < 0) + return r; + r = pidref_verify(b); + if (r < 0) + return r; + + return result; } #endif /* NM_IGNORED */ bool is_main_thread(void) { - static thread_local int cached = 0; + static thread_local int cached = -1; - if (_unlikely_(cached == 0)) - cached = getpid_cached() == gettid() ? 1 : -1; + if (cached < 0) + cached = getpid_cached() == gettid(); - return cached > 0; + return cached; } #if 0 /* NM_IGNORED */ @@ -1423,11 +1483,6 @@ int must_be_root(void) { return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Need to be root."); } -static void restore_sigsetp(sigset_t **ssp) { - if (*ssp) - (void) sigprocmask(SIG_SETMASK, *ssp, NULL); -} - pid_t clone_with_nested_stack(int (*fn)(void *), int flags, void *userdata) { size_t ps; pid_t pid; @@ -1467,6 +1522,11 @@ pid_t clone_with_nested_stack(int (*fn)(void *), int flags, void *userdata) { return pid; } +static void restore_sigsetp(sigset_t **ssp) { + if (*ssp) + (void) sigprocmask(SIG_SETMASK, *ssp, NULL); +} + static int fork_flags_to_signal(ForkFlags flags) { return (flags & FORK_DEATHSIG_SIGTERM) ? SIGTERM : (flags & FORK_DEATHSIG_SIGINT) ? SIGINT : @@ -1487,8 +1547,8 @@ int safe_fork_full( bool block_signals = false, block_all = false, intermediary = false; int prio, r; - assert(!FLAGS_SET(flags, FORK_DETACH) || !ret_pid); - assert(!FLAGS_SET(flags, FORK_DETACH|FORK_WAIT)); + assert(!FLAGS_SET(flags, FORK_DETACH) || + (!ret_pid && (flags & (FORK_WAIT|FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGKILL)) == 0)); /* A wrapper around fork(), that does a couple of important initializations in addition to mere forking. Always * returns the child's PID in *ret_pid. Returns == 0 in the child, and > 0 in the parent. */ @@ -1519,15 +1579,12 @@ int safe_fork_full( } if (block_signals) { - if (sigprocmask(SIG_SETMASK, &ss, &saved_ss) < 0) - return log_full_errno(prio, errno, "Failed to set signal mask: %m"); + if (sigprocmask(SIG_BLOCK, &ss, &saved_ss) < 0) + return log_full_errno(prio, errno, "Failed to block signal mask: %m"); saved_ssp = &saved_ss; } if (FLAGS_SET(flags, FORK_DETACH)) { - assert(!FLAGS_SET(flags, FORK_WAIT)); - assert(!ret_pid); - /* Fork off intermediary child if needed */ r = is_reaper_process(); @@ -1549,11 +1606,12 @@ int safe_fork_full( } } - if ((flags & (FORK_NEW_MOUNTNS|FORK_NEW_USERNS|FORK_NEW_NETNS)) != 0) + if ((flags & (FORK_NEW_MOUNTNS|FORK_NEW_USERNS|FORK_NEW_NETNS|FORK_NEW_PIDNS)) != 0) pid = raw_clone(SIGCHLD| (FLAGS_SET(flags, FORK_NEW_MOUNTNS) ? CLONE_NEWNS : 0) | (FLAGS_SET(flags, FORK_NEW_USERNS) ? CLONE_NEWUSER : 0) | - (FLAGS_SET(flags, FORK_NEW_NETNS) ? CLONE_NEWNET : 0)); + (FLAGS_SET(flags, FORK_NEW_NETNS) ? CLONE_NEWNET : 0) | + (FLAGS_SET(flags, FORK_NEW_PIDNS) ? CLONE_NEWPID : 0)); else pid = fork(); if (pid < 0) @@ -1748,6 +1806,9 @@ int safe_fork_full( } } + if (FLAGS_SET(flags, FORK_FREEZE)) + freeze(); + if (ret_pid) *ret_pid = getpid_cached(); @@ -1765,12 +1826,16 @@ int pidref_safe_fork_full( pid_t pid; int r, q; - assert(!FLAGS_SET(flags, FORK_WAIT)); - r = safe_fork_full(name, stdio_fds, except_fds, n_except_fds, flags, &pid); - if (r < 0) + if (r < 0 || !ret_pid) return r; + if (r > 0 && FLAGS_SET(flags, FORK_WAIT)) { + /* If we are in the parent and successfully waited, then the process doesn't exist anymore */ + *ret_pid = PIDREF_NULL; + return r; + } + q = pidref_set_pid(ret_pid, pid); if (q < 0) /* Let's not fail for this, no matter what, the process exists after all, and that's key */ *ret_pid = PIDREF_MAKE_FROM_PID(pid); @@ -1841,6 +1906,9 @@ int namespace_fork( int set_oom_score_adjust(int value) { char t[DECIMAL_STR_MAX(int)]; + if (!oom_score_adjust_is_valid(value)) + return -EINVAL; + xsprintf(t, "%i", value); return write_string_file("/proc/self/oom_score_adj", t, @@ -1857,67 +1925,17 @@ int get_oom_score_adjust(int *ret) { delete_trailing_chars(t, WHITESPACE); - assert_se(safe_atoi(t, &a) >= 0); - assert_se(oom_score_adjust_is_valid(a)); - - if (ret) - *ret = a; - return 0; -} - -int pidfd_get_pid(int fd, pid_t *ret) { - char path[STRLEN("/proc/self/fdinfo/") + DECIMAL_STR_MAX(int)]; - _cleanup_free_ char *fdinfo = NULL; - char *p; - int r; - - /* Converts a pidfd into a pid. Well known errors: - * - * -EBADF → fd invalid - * -ENOSYS → /proc/ not mounted - * -ENOTTY → fd valid, but not a pidfd - * -EREMOTE → fd valid, but pid is in another namespace we cannot translate to the local one - * -ESRCH → fd valid, but process is already reaped - */ - - if (fd < 0) - return -EBADF; - - xsprintf(path, "/proc/self/fdinfo/%i", fd); - - r = read_full_virtual_file(path, &fdinfo, NULL); - if (r == -ENOENT) /* if fdinfo doesn't exist we assume the process does not exist */ - return proc_mounted() > 0 ? -EBADF : -ENOSYS; + r = safe_atoi(t, &a); if (r < 0) return r; - p = find_line_startswith(fdinfo, "Pid:"); - if (!p) - return -ENOTTY; /* not a pidfd? */ - - p += strspn(p, WHITESPACE); - p[strcspn(p, WHITESPACE)] = 0; - - if (streq(p, "0")) - return -EREMOTE; /* PID is in foreign PID namespace? */ - if (streq(p, "-1")) - return -ESRCH; /* refers to reaped process? */ - - return parse_pid(p, ret); -} - -int pidfd_verify_pid(int pidfd, pid_t pid) { - pid_t current_pid; - int r; - - assert(pidfd >= 0); - assert(pid > 0); + if (!oom_score_adjust_is_valid(a)) + return -ENODATA; - r = pidfd_get_pid(pidfd, ¤t_pid); - if (r < 0) - return r; + if (ret) + *ret = a; - return current_pid != pid ? -ESRCH : 0; + return 0; } static int rlimit_to_nice(rlim_t limit) { @@ -1931,17 +1949,15 @@ static int rlimit_to_nice(rlim_t limit) { } int setpriority_closest(int priority) { - int current, limit, saved_errno; struct rlimit highest; + int r, current, limit; /* Try to set requested nice level */ - if (setpriority(PRIO_PROCESS, 0, priority) >= 0) + r = RET_NERRNO(setpriority(PRIO_PROCESS, 0, priority)); + if (r >= 0) return 1; - - /* Permission failed */ - saved_errno = -errno; - if (!ERRNO_IS_PRIVILEGE(saved_errno)) - return saved_errno; + if (!ERRNO_IS_NEG_PRIVILEGE(r)) + return r; errno = 0; current = getpriority(PRIO_PROCESS, 0); @@ -1955,24 +1971,21 @@ int setpriority_closest(int priority) { * then the whole setpriority() system call is blocked to us, hence let's propagate the error * right-away */ if (priority > current) - return saved_errno; + return r; if (getrlimit(RLIMIT_NICE, &highest) < 0) return -errno; limit = rlimit_to_nice(highest.rlim_cur); - /* We are already less nice than limit allows us */ - if (current < limit) { - log_debug("Cannot raise nice level, permissions and the resource limit do not allow it."); - return 0; - } - - /* Push to the allowed limit */ - if (setpriority(PRIO_PROCESS, 0, limit) < 0) - return -errno; + /* Push to the allowed limit if we're higher than that. Note that we could also be less nice than + * limit allows us, but still higher than what's requested. In that case our current value is + * the best choice. */ + if (current > limit) + if (setpriority(PRIO_PROCESS, 0, limit) < 0) + return -errno; - log_debug("Cannot set requested nice level (%i), used next best (%i).", priority, limit); + log_debug("Cannot set requested nice level (%i), using next best (%i).", priority, MIN(current, limit)); return 0; } @@ -1992,7 +2005,8 @@ _noreturn_ void freeze(void) { break; } - /* waitid() failed with an unexpected error, things are really borked. Freeze now! */ + /* waitid() failed with an ECHLD error (because there are no left-over child processes) or any other + * (unexpected) error. Freeze for good now! */ for (;;) pause(); } @@ -2064,7 +2078,7 @@ int posix_spawn_wrapper( const char *cgroup, PidRef *ret_pidref) { - short flags = POSIX_SPAWN_SETSIGMASK|POSIX_SPAWN_SETSIGDEF; + short flags = POSIX_SPAWN_SETSIGMASK; posix_spawnattr_t attr; sigset_t mask; int r; @@ -2075,7 +2089,7 @@ int posix_spawn_wrapper( * issues. * * Also, move the newly-created process into 'cgroup' through POSIX_SPAWN_SETCGROUP (clone3()) - * if available. Note that CLONE_INTO_CGROUP is only supported on cgroup v2. + * if available. * returns 1: We're already in the right cgroup * 0: 'cgroup' not specified or POSIX_SPAWN_SETCGROUP is not supported. The caller * needs to call 'cg_attach' on their own */ @@ -2094,9 +2108,10 @@ int posix_spawn_wrapper( _unused_ _cleanup_(posix_spawnattr_destroyp) posix_spawnattr_t *attr_destructor = &attr; #if HAVE_PIDFD_SPAWN + static bool have_clone_into_cgroup = true; /* kernel 5.7+ */ _cleanup_close_ int cgroup_fd = -EBADF; - if (cgroup) { + if (cgroup && have_clone_into_cgroup) { _cleanup_free_ char *resolved_cgroup = NULL; r = cg_get_path_and_check( @@ -2130,25 +2145,38 @@ int posix_spawn_wrapper( _cleanup_close_ int pidfd = -EBADF; r = pidfd_spawn(&pidfd, path, NULL, &attr, argv, envp); - if (r == 0) { - r = pidref_set_pidfd_consume(ret_pidref, TAKE_FD(pidfd)); - if (r < 0) - return r; + if (ERRNO_IS_NOT_SUPPORTED(r) && FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP) && cg_is_threaded(cgroup) > 0) + return -EUCLEAN; /* clone3() could also return EOPNOTSUPP if the target cgroup is in threaded mode, + turn that into something recognizable */ + if ((ERRNO_IS_NOT_SUPPORTED(r) || ERRNO_IS_PRIVILEGE(r) || r == E2BIG) && + FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP)) { + /* Compiled on a newer host, or seccomp&friends blocking clone3()? Fallback, but + * need to disable POSIX_SPAWN_SETCGROUP, which is what redirects to clone3(). + * Note that we might get E2BIG here since some kernels (e.g. 5.4) support clone3() + * but not CLONE_INTO_CGROUP. */ + + /* CLONE_INTO_CGROUP definitely won't work, hence remember the fact so that we don't + * retry every time. */ + have_clone_into_cgroup = false; + + flags &= ~POSIX_SPAWN_SETCGROUP; + r = posix_spawnattr_setflags(&attr, flags); + if (r != 0) + return -r; - return FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP); + r = pidfd_spawn(&pidfd, path, NULL, &attr, argv, envp); } - if (!(ERRNO_IS_NOT_SUPPORTED(r) || ERRNO_IS_PRIVILEGE(r))) - return -r; - - /* Compiled on a newer host, or seccomp&friends blocking clone3()? Fallback, but need to change the - * flags to remove the cgroup one, which is what redirects to clone3() */ - flags &= ~POSIX_SPAWN_SETCGROUP; - r = posix_spawnattr_setflags(&attr, flags); if (r != 0) return -r; -#endif + r = pidref_set_pidfd_consume(ret_pidref, TAKE_FD(pidfd)); + if (r < 0) + return r; + + return FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP); +#else pid_t pid; + r = posix_spawn(&pid, path, NULL, &attr, argv, envp); if (r != 0) return -r; @@ -2158,6 +2186,7 @@ int posix_spawn_wrapper( return r; return 0; /* We did not use CLONE_INTO_CGROUP so return 0, the caller will have to move the child */ +#endif } int proc_dir_open(DIR **ret) { @@ -2248,4 +2277,46 @@ static const char* const sched_policy_table[] = { }; DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX); + +_noreturn_ void report_errno_and_exit(int errno_fd, int error) { + int r; + + if (error >= 0) + _exit(EXIT_SUCCESS); + + assert(errno_fd >= 0); + + r = loop_write(errno_fd, &error, sizeof(error)); + if (r < 0) + log_debug_errno(r, "Failed to write errno to errno_fd=%d: %m", errno_fd); + + _exit(EXIT_FAILURE); +} + +int read_errno(int errno_fd) { + int r; + + assert(errno_fd >= 0); + + /* The issue here is that it's impossible to distinguish between an error code returned by child and + * IO error arose when reading it. So, the function logs errors and return EIO for the later case. */ + + ssize_t n = loop_read(errno_fd, &r, sizeof(r), /* do_poll = */ false); + if (n < 0) { + log_debug_errno(n, "Failed to read errno: %m"); + return -EIO; + } + if (n == sizeof(r)) { + if (r == 0) + return 0; + if (r < 0) /* child process reported an error, return it */ + return log_debug_errno(r, "Child process failed with errno: %m"); + return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Received an errno, but it's a positive value."); + } + if (n != 0) + return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Received unexpected amount of bytes while reading errno."); + + /* the process exited without reporting an error, assuming success */ + return 0; +} #endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/process-util.h b/src/libnm-systemd-shared/src/basic/process-util.h index 49350065..19ac55dd 100644 --- a/src/libnm-systemd-shared/src/basic/process-util.h +++ b/src/libnm-systemd-shared/src/basic/process-util.h @@ -14,7 +14,7 @@ #include "alloc-util.h" #include "format-util.h" #include "macro.h" -#include "namespace-util.h" +#include "pidref.h" #include "time-util.h" #define procfs_file_alloca(pid, field) \ @@ -49,19 +49,18 @@ int get_process_exe(pid_t pid, char **ret); int pid_get_uid(pid_t pid, uid_t *ret); int pidref_get_uid(const PidRef *pid, uid_t *ret); int get_process_gid(pid_t pid, gid_t *ret); -int get_process_capeff(pid_t pid, char **ret); int get_process_cwd(pid_t pid, char **ret); int get_process_root(pid_t pid, char **ret); int get_process_environ(pid_t pid, char **ret); -int get_process_ppid(pid_t pid, pid_t *ret); -int pid_get_start_time(pid_t pid, uint64_t *ret); -int pidref_get_start_time(const PidRef* pid, uint64_t *ret); +int pid_get_ppid(pid_t pid, pid_t *ret); +int pidref_get_ppid(const PidRef *pidref, pid_t *ret); +int pidref_get_ppid_as_pidref(const PidRef *pidref, PidRef *ret); +int pid_get_start_time(pid_t pid, usec_t *ret); +int pidref_get_start_time(const PidRef *pid, usec_t *ret); int get_process_umask(pid_t pid, mode_t *ret); int container_get_leader(const char *machine, pid_t *pid); -int namespace_get_leader(pid_t pid, NamespaceType type, pid_t *ret); - int wait_for_terminate(pid_t pid, siginfo_t *status); typedef enum WaitFlags { @@ -91,10 +90,10 @@ int getenv_for_pid(pid_t pid, const char *field, char **_value); int pid_is_alive(pid_t pid); int pidref_is_alive(const PidRef *pidref); int pid_is_unwaited(pid_t pid); -int pidref_is_unwaited(const PidRef *pidref); +int pidref_is_unwaited(PidRef *pidref); int pid_is_my_child(pid_t pid); -int pidref_is_my_child(const PidRef *pidref); -int pid_from_same_root_fs(pid_t pid); +int pidref_is_my_child(PidRef *pidref); +int pidref_from_same_root_fs(PidRef *a, PidRef *b); bool is_main_thread(void); @@ -113,12 +112,12 @@ bool oom_score_adjust_is_valid(int oa); #define OPINIONATED_PERSONALITY_MASK 0xFFUL unsigned long personality_from_string(const char *p); -const char *personality_to_string(unsigned long); +const char* personality_to_string(unsigned long); int safe_personality(unsigned long p); int opinionated_personality(unsigned long *ret); -const char *sigchld_code_to_string(int i) _const_; +const char* sigchld_code_to_string(int i) _const_; int sigchld_code_from_string(const char *s) _pure_; int sched_policy_to_string_alloc(int i, char **s); @@ -149,9 +148,15 @@ static inline bool sched_priority_is_valid(int i) { return i >= 0 && i <= sched_get_priority_max(SCHED_RR); } +#define PID_AUTOMATIC ((pid_t) INT_MIN) /* special value indicating "acquire pid from connection peer" */ + static inline bool pid_is_valid(pid_t p) { return p > 0; } + +static inline bool pid_is_automatic(pid_t p) { + return p == PID_AUTOMATIC; +} #endif /* NM_IGNORED */ pid_t getpid_cached(void); @@ -161,7 +166,7 @@ int must_be_root(void); pid_t clone_with_nested_stack(int (*fn)(void *), int flags, void *userdata); -/* 💣 Note that FORK_NEW_USERNS, FORK_NEW_MOUNTNS, or FORK_NEW_NETNS should not be called in threaded +/* 💣 Note that FORK_NEW_USERNS, FORK_NEW_MOUNTNS, FORK_NEW_NETNS or FORK_NEW_PIDNS should not be called in threaded * programs, because they cause us to use raw_clone() which does not synchronize the glibc malloc() locks, * and thus will cause deadlocks if the parent uses threads and the child does memory allocations. Hence: if * the parent is threaded these flags may not be used. These flags cannot be used if the parent uses threads @@ -176,18 +181,20 @@ typedef enum ForkFlags { FORK_REOPEN_LOG = 1 << 6, /* Reopen log connection */ FORK_LOG = 1 << 7, /* Log above LOG_DEBUG log level about failures */ FORK_WAIT = 1 << 8, /* Wait until child exited */ - FORK_NEW_MOUNTNS = 1 << 9, /* Run child in its own mount namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */ - FORK_MOUNTNS_SLAVE = 1 << 10, /* Make child's mount namespace MS_SLAVE */ - FORK_PRIVATE_TMP = 1 << 11, /* Mount new /tmp/ in the child (combine with FORK_NEW_MOUNTNS!) */ - FORK_RLIMIT_NOFILE_SAFE = 1 << 12, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */ - FORK_STDOUT_TO_STDERR = 1 << 13, /* Make stdout a copy of stderr */ - FORK_FLUSH_STDIO = 1 << 14, /* fflush() stdout (and stderr) before forking */ - FORK_NEW_USERNS = 1 << 15, /* Run child in its own user namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */ - FORK_CLOEXEC_OFF = 1 << 16, /* In the child: turn off O_CLOEXEC on all fds in except_fds[] */ - FORK_KEEP_NOTIFY_SOCKET = 1 << 17, /* Unless this specified, $NOTIFY_SOCKET will be unset. */ - FORK_DETACH = 1 << 18, /* Double fork if needed to ensure PID1/subreaper is parent */ - FORK_NEW_NETNS = 1 << 19, /* Run child in its own network namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */ - FORK_PACK_FDS = 1 << 20, /* Rearrange the passed FDs to be FD 3,4,5,etc. Updates the array in place (combine with FORK_CLOSE_ALL_FDS!) */ + FORK_MOUNTNS_SLAVE = 1 << 9, /* Make child's mount namespace MS_SLAVE */ + FORK_PRIVATE_TMP = 1 << 10, /* Mount new /tmp/ in the child (combine with FORK_NEW_MOUNTNS!) */ + FORK_RLIMIT_NOFILE_SAFE = 1 << 11, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */ + FORK_STDOUT_TO_STDERR = 1 << 12, /* Make stdout a copy of stderr */ + FORK_FLUSH_STDIO = 1 << 13, /* fflush() stdout (and stderr) before forking */ + FORK_CLOEXEC_OFF = 1 << 14, /* In the child: turn off O_CLOEXEC on all fds in except_fds[] */ + FORK_KEEP_NOTIFY_SOCKET = 1 << 15, /* Unless this specified, $NOTIFY_SOCKET will be unset. */ + FORK_DETACH = 1 << 16, /* Double fork if needed to ensure PID1/subreaper is parent */ + FORK_PACK_FDS = 1 << 17, /* Rearrange the passed FDs to be FD 3,4,5,etc. Updates the array in place (combine with FORK_CLOSE_ALL_FDS!) */ + FORK_NEW_MOUNTNS = 1 << 18, /* Run child in its own mount namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */ + FORK_NEW_USERNS = 1 << 19, /* Run child in its own user namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */ + FORK_NEW_NETNS = 1 << 20, /* Run child in its own network namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */ + FORK_NEW_PIDNS = 1 << 21, /* Run child in its own PID namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */ + FORK_FREEZE = 1 << 22, /* Don't return in child, just call freeze() instead */ } ForkFlags; int safe_fork_full( @@ -245,9 +252,6 @@ assert_cc(TASKS_MAX <= (unsigned long) PID_T_MAX); /* Like TAKE_PTR() but for pid_t, resetting them to 0 */ #define TAKE_PID(pid) TAKE_GENERIC(pid, pid_t, 0) -int pidfd_get_pid(int fd, pid_t *ret); -int pidfd_verify_pid(int pidfd, pid_t pid); - int setpriority_closest(int priority); _noreturn_ void freeze(void); @@ -267,3 +271,6 @@ int posix_spawn_wrapper( int proc_dir_open(DIR **ret); int proc_dir_read(DIR *d, pid_t *ret); int proc_dir_read_pidref(DIR *d, PidRef *ret); + +_noreturn_ void report_errno_and_exit(int errno_fd, int error); +int read_errno(int errno_fd); diff --git a/src/libnm-systemd-shared/src/basic/random-util.c b/src/libnm-systemd-shared/src/basic/random-util.c index c7b95516..1e1a24bd 100644 --- a/src/libnm-systemd-shared/src/basic/random-util.c +++ b/src/libnm-systemd-shared/src/basic/random-util.c @@ -10,29 +10,28 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> +#include <sys/auxv.h> #include <sys/ioctl.h> #include <sys/time.h> -#if HAVE_SYS_AUXV_H -# include <sys/auxv.h> -#endif - #include "alloc-util.h" #include "env-util.h" #include "errno-util.h" #include "fd-util.h" #include "fileio.h" #include "io-util.h" +#include "iovec-util.h" #include "missing_random.h" #include "missing_syscall.h" #include "missing_threads.h" #include "parse-util.h" +#include "pidfd-util.h" #include "process-util.h" #include "random-util.h" #include "sha256.h" #include "time-util.h" -/* This is a "best effort" kind of thing, but has no real security value. So, this should only be used by +/* This is a "best effort" kind of thing, but has no real security value. So, this should only be used by * random_bytes(), which is not meant for crypto. This could be made better, but we're *not* trying to roll a * userspace prng here, or even have forward secrecy, but rather just do the shortest thing that is at least * better than libc rand(). */ @@ -43,10 +42,10 @@ static void fallback_random_bytes(void *p, size_t n) { uint64_t call_id, block_id; usec_t stamp_mono, stamp_real; pid_t pid, tid; + uint64_t pidfdid; uint8_t auxval[16]; } state = { /* Arbitrary domain separation to prevent other usage of AT_RANDOM from clashing. */ - .label = "systemd fallback random bytes v1", .call_id = fallback_counter++, .stamp_mono = now(CLOCK_MONOTONIC), .stamp_real = now(CLOCK_REALTIME), @@ -54,9 +53,9 @@ static void fallback_random_bytes(void *p, size_t n) { .tid = gettid(), }; -#if HAVE_SYS_AUXV_H + memcpy(state.label, "systemd fallback random bytes v1", sizeof(state.label)); memcpy(state.auxval, ULONG_TO_PTR(getauxval(AT_RANDOM)), sizeof(state.auxval)); -#endif + (void) pidfd_get_inode_id_self_cached(&state.pidfdid); while (n > 0) { struct sha256_ctx ctx; @@ -77,8 +76,9 @@ static void fallback_random_bytes(void *p, size_t n) { } void random_bytes(void *p, size_t n) { - static bool have_getrandom = true, have_grndinsecure = true; - _cleanup_close_ int fd = -EBADF; + static bool have_grndinsecure = true; + + assert(p || n == 0); if (n == 0) return; @@ -86,32 +86,26 @@ void random_bytes(void *p, size_t n) { for (;;) { ssize_t l; - if (!have_getrandom) - break; - l = getrandom(p, n, have_grndinsecure ? GRND_INSECURE : GRND_NONBLOCK); - if (l > 0) { - if ((size_t) l == n) - return; /* Done reading, success. */ - p = (uint8_t *) p + l; - n -= l; - continue; /* Interrupted by a signal; keep going. */ - } else if (l == 0) - break; /* Weird, so fallback to /dev/urandom. */ - else if (ERRNO_IS_NOT_SUPPORTED(errno)) { - have_getrandom = false; - break; /* No syscall, so fallback to /dev/urandom. */ - } else if (errno == EINVAL && have_grndinsecure) { + if (l < 0 && errno == EINVAL && have_grndinsecure) { + /* No GRND_INSECURE; fallback to GRND_NONBLOCK. */ have_grndinsecure = false; - continue; /* No GRND_INSECURE; fallback to GRND_NONBLOCK. */ - } else if (errno == EAGAIN && !have_grndinsecure) - break; /* Will block, but no GRND_INSECURE, so fallback to /dev/urandom. */ + continue; + } + if (l <= 0) + break; /* Will block (with GRND_NONBLOCK), or unexpected error. Give up and fallback + to /dev/urandom. */ + + if ((size_t) l == n) + return; /* Done reading, success. */ - break; /* Unexpected, so just give up and fallback to /dev/urandom. */ + p = (uint8_t *) p + l; + n -= l; + /* Interrupted by a signal; keep going. */ } - fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); - if (fd >= 0 && loop_read_exact(fd, p, n, false) == 0) + _cleanup_close_ int fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd >= 0 && loop_read_exact(fd, p, n, false) >= 0) return; /* This is a terrible fallback. Oh well. */ @@ -119,8 +113,7 @@ void random_bytes(void *p, size_t n) { } int crypto_random_bytes(void *p, size_t n) { - static bool have_getrandom = true, seen_initialized = false; - _cleanup_close_ int fd = -EBADF; + assert(p || n == 0); if (n == 0) return 0; @@ -128,42 +121,37 @@ int crypto_random_bytes(void *p, size_t n) { for (;;) { ssize_t l; - if (!have_getrandom) - break; - l = getrandom(p, n, 0); - if (l > 0) { - if ((size_t) l == n) - return 0; /* Done reading, success. */ - p = (uint8_t *) p + l; - n -= l; - continue; /* Interrupted by a signal; keep going. */ - } else if (l == 0) + if (l < 0) + return -errno; + if (l == 0) return -EIO; /* Weird, should never happen. */ - else if (ERRNO_IS_NOT_SUPPORTED(errno)) { - have_getrandom = false; - break; /* No syscall, so fallback to /dev/urandom. */ - } - return -errno; - } - if (!seen_initialized) { - _cleanup_close_ int ready_fd = -EBADF; - int r; + if ((size_t) l == n) + return 0; /* Done reading, success. */ - ready_fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY); - if (ready_fd < 0) - return -errno; - r = fd_wait_for_event(ready_fd, POLLIN, USEC_INFINITY); - if (r < 0) - return r; - seen_initialized = true; + p = (uint8_t *) p + l; + n -= l; + /* Interrupted by a signal; keep going. */ } +} + +int crypto_random_bytes_allocate_iovec(size_t n, struct iovec *ret) { + _cleanup_free_ void *p = NULL; + int r; + + assert(ret); + + p = malloc(MAX(n, 1U)); + if (!p) + return -ENOMEM; + + r = crypto_random_bytes(p, n); + if (r < 0) + return r; - fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); - if (fd < 0) - return -errno; - return loop_read_exact(fd, p, n, false); + *ret = IOVEC_MAKE(TAKE_PTR(p), n); + return 0; } #if 0 /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/random-util.h b/src/libnm-systemd-shared/src/basic/random-util.h index b1a4d109..0b5ba771 100644 --- a/src/libnm-systemd-shared/src/basic/random-util.h +++ b/src/libnm-systemd-shared/src/basic/random-util.h @@ -4,9 +4,11 @@ #include <stdbool.h> #include <stddef.h> #include <stdint.h> +#include <sys/uio.h> void random_bytes(void *p, size_t n); /* Returns random bytes suitable for most uses, but may be insecure sometimes. */ int crypto_random_bytes(void *p, size_t n); /* Returns secure random bytes after waiting for the RNG to initialize. */ +int crypto_random_bytes_allocate_iovec(size_t n, struct iovec *ret); static inline uint64_t random_u64(void) { uint64_t u; diff --git a/src/libnm-systemd-shared/src/basic/ratelimit.c b/src/libnm-systemd-shared/src/basic/ratelimit.c index a28c8122..8036f66c 100644 --- a/src/libnm-systemd-shared/src/basic/ratelimit.c +++ b/src/libnm-systemd-shared/src/basic/ratelimit.c @@ -10,37 +10,37 @@ /* Modelled after Linux' lib/ratelimit.c by Dave Young * <hidave.darkstar@gmail.com>, which is licensed GPLv2. */ -bool ratelimit_below(RateLimit *r) { +bool ratelimit_below(RateLimit *rl) { usec_t ts; - assert(r); + assert(rl); - if (!ratelimit_configured(r)) + if (!ratelimit_configured(rl)) return true; ts = now(CLOCK_MONOTONIC); - if (r->begin <= 0 || - usec_sub_unsigned(ts, r->begin) > r->interval) { - r->begin = ts; /* Start a new time window */ - r->num = 1; /* Reset counter */ + if (rl->begin <= 0 || + usec_sub_unsigned(ts, rl->begin) > rl->interval) { + rl->begin = ts; /* Start a new time window */ + rl->num = 1; /* Reset counter */ return true; } - if (_unlikely_(r->num == UINT_MAX)) + if (_unlikely_(rl->num == UINT_MAX)) return false; - r->num++; - return r->num <= r->burst; + rl->num++; + return rl->num <= rl->burst; } -unsigned ratelimit_num_dropped(RateLimit *r) { - assert(r); +unsigned ratelimit_num_dropped(const RateLimit *rl) { + assert(rl); - if (r->num == UINT_MAX) /* overflow, return as special case */ + if (rl->num == UINT_MAX) /* overflow, return as special case */ return UINT_MAX; - return LESS_BY(r->num, r->burst); + return LESS_BY(rl->num, rl->burst); } usec_t ratelimit_end(const RateLimit *rl) { diff --git a/src/libnm-systemd-shared/src/basic/ratelimit.h b/src/libnm-systemd-shared/src/basic/ratelimit.h index 492ea3b4..7801ef42 100644 --- a/src/libnm-systemd-shared/src/basic/ratelimit.h +++ b/src/libnm-systemd-shared/src/basic/ratelimit.h @@ -18,13 +18,13 @@ static inline void ratelimit_reset(RateLimit *rl) { rl->num = rl->begin = 0; } -static inline bool ratelimit_configured(RateLimit *rl) { +static inline bool ratelimit_configured(const RateLimit *rl) { return rl->interval > 0 && rl->burst > 0; } -bool ratelimit_below(RateLimit *r); +bool ratelimit_below(RateLimit *rl); -unsigned ratelimit_num_dropped(RateLimit *r); +unsigned ratelimit_num_dropped(const RateLimit *rl); usec_t ratelimit_end(const RateLimit *rl); usec_t ratelimit_left(const RateLimit *rl); diff --git a/src/libnm-systemd-shared/src/basic/sha256.c b/src/libnm-systemd-shared/src/basic/sha256.c new file mode 100644 index 00000000..88871a6b --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/sha256.c @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-shared.h" + +#include <unistd.h> + +#include "hexdecoct.h" +#include "macro.h" +#include "sha256.h" + +int sha256_fd(int fd, uint64_t max_size, uint8_t ret[static SHA256_DIGEST_SIZE]) { + struct sha256_ctx ctx; + uint64_t total_size = 0; + + sha256_init_ctx(&ctx); + + for (;;) { + uint8_t buffer[64 * 1024]; + ssize_t n; + + n = read(fd, buffer, sizeof(buffer)); + if (n < 0) + return -errno; + if (n == 0) + break; + + if (!INC_SAFE(&total_size, n) || total_size > max_size) + return -EFBIG; + + sha256_process_bytes(buffer, n, &ctx); + } + + sha256_finish_ctx(&ctx, ret); + return 0; +} + +int parse_sha256(const char *s, uint8_t ret[static SHA256_DIGEST_SIZE]) { + _cleanup_free_ uint8_t *data = NULL; + size_t size = 0; + int r; + + if (!sha256_is_valid(s)) + return -EINVAL; + + r = unhexmem_full(s, SHA256_DIGEST_SIZE * 2, false, (void**) &data, &size); + if (r < 0) + return r; + assert(size == SHA256_DIGEST_SIZE); + + memcpy(ret, data, size); + return 0; +} diff --git a/src/libnm-systemd-shared/src/basic/sha256.h b/src/libnm-systemd-shared/src/basic/sha256.h new file mode 100644 index 00000000..95bac1bc --- /dev/null +++ b/src/libnm-systemd-shared/src/basic/sha256.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#pragma once + +#include <stdint.h> + +#include "sha256-fundamental.h" +#include "string-util.h" + +int sha256_fd(int fd, uint64_t max_size, uint8_t ret[static SHA256_DIGEST_SIZE]); + +int parse_sha256(const char *s, uint8_t res[static SHA256_DIGEST_SIZE]); + +static inline bool sha256_is_valid(const char *s) { + return s && in_charset(s, HEXDIGITS) && (strlen(s) == SHA256_DIGEST_SIZE * 2); +} diff --git a/src/libnm-systemd-shared/src/basic/signal-util.c b/src/libnm-systemd-shared/src/basic/signal-util.c index 95c86584..05b2b50d 100644 --- a/src/libnm-systemd-shared/src/basic/signal-util.c +++ b/src/libnm-systemd-shared/src/basic/signal-util.c @@ -17,10 +17,6 @@ #if 0 /* NM_IGNORED */ int reset_all_signal_handlers(void) { - static const struct sigaction sa = { - .sa_handler = SIG_DFL, - .sa_flags = SA_RESTART, - }; int ret = 0, r; for (int sig = 1; sig < _NSIG; sig++) { @@ -31,7 +27,7 @@ int reset_all_signal_handlers(void) { /* On Linux the first two RT signals are reserved by glibc, and sigaction() will return * EINVAL for them. */ - r = RET_NERRNO(sigaction(sig, &sa, NULL)); + r = RET_NERRNO(sigaction(sig, &sigaction_default, NULL)); if (r != -EINVAL) RET_GATHER(ret, r); } @@ -154,7 +150,7 @@ static const char *const static_signal_table[] = { DEFINE_PRIVATE_STRING_TABLE_LOOKUP(static_signal, int); -const char *signal_to_string(int signo) { +const char* signal_to_string(int signo) { static thread_local char buf[STRLEN("RTMIN+") + DECIMAL_STR_MAX(int)]; const char *name; @@ -271,7 +267,7 @@ int pop_pending_signal_internal(int sig, ...) { if (r < 0) return r; - r = sigtimedwait(&ss, NULL, &(struct timespec) { 0, 0 }); + r = sigtimedwait(&ss, NULL, &(const struct timespec) {}); if (r < 0) { if (errno == EAGAIN) return 0; @@ -298,4 +294,35 @@ void propagate_signal(int sig, siginfo_t *siginfo) { if (rt_tgsigqueueinfo(p, gettid(), sig, siginfo) < 0) assert_se(kill(p, sig) >= 0); } + +const struct sigaction sigaction_ignore = { + .sa_handler = SIG_IGN, + .sa_flags = SA_RESTART, +}; + +const struct sigaction sigaction_default = { + .sa_handler = SIG_DFL, + .sa_flags = SA_RESTART, +}; + +const struct sigaction sigaction_nop_nocldstop = { + .sa_handler = nop_signal_handler, + .sa_flags = SA_NOCLDSTOP|SA_RESTART, +}; + +int parse_signo(const char *s, int *ret) { + int sig, r; + + r = safe_atoi(s, &sig); + if (r < 0) + return r; + + if (!SIGNAL_VALID(sig)) + return -EINVAL; + + if (ret) + *ret = sig; + + return 0; +} #endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/signal-util.h b/src/libnm-systemd-shared/src/basic/signal-util.h index 8826fbeb..dc2b9de1 100644 --- a/src/libnm-systemd-shared/src/basic/signal-util.h +++ b/src/libnm-systemd-shared/src/basic/signal-util.h @@ -12,19 +12,13 @@ int sigaction_many_internal(const struct sigaction *sa, ...); #define ignore_signals(...) \ sigaction_many_internal( \ - &(const struct sigaction) { \ - .sa_handler = SIG_IGN, \ - .sa_flags = SA_RESTART \ - }, \ + &sigaction_ignore, \ __VA_ARGS__, \ -1) #define default_signals(...) \ sigaction_many_internal( \ - &(const struct sigaction) { \ - .sa_handler = SIG_DFL, \ - .sa_flags = SA_RESTART \ - }, \ + &sigaction_default, \ __VA_ARGS__, \ -1) @@ -34,10 +28,10 @@ int sigaction_many_internal(const struct sigaction *sa, ...); int sigset_add_many_internal(sigset_t *ss, ...); #define sigset_add_many(...) sigset_add_many_internal(__VA_ARGS__, -1) -int sigprocmask_many_internal(int how, sigset_t *old, ...); +int sigprocmask_many_internal(int how, sigset_t *ret_old_mask, ...); #define sigprocmask_many(...) sigprocmask_many_internal(__VA_ARGS__, -1) -const char *signal_to_string(int i) _const_; +const char* signal_to_string(int i) _const_; int signal_from_string(const char *s) _pure_; void nop_signal_handler(int sig); @@ -52,6 +46,7 @@ static inline void block_signals_reset(sigset_t *ss) { assert_se(sigprocmask_many(SIG_BLOCK, &_t, __VA_ARGS__) >= 0); \ _t; \ }) +#define SIGNO_INVALID (-EINVAL) static inline bool SIGNAL_VALID(int signo) { return signo > 0 && signo < _NSIG; @@ -70,3 +65,9 @@ int pop_pending_signal_internal(int sig, ...); #define pop_pending_signal(...) pop_pending_signal_internal(__VA_ARGS__, -1) void propagate_signal(int sig, siginfo_t *siginfo); + +extern const struct sigaction sigaction_ignore; +extern const struct sigaction sigaction_default; +extern const struct sigaction sigaction_nop_nocldstop; + +int parse_signo(const char *s, int *ret); diff --git a/src/libnm-systemd-shared/src/basic/socket-util.c b/src/libnm-systemd-shared/src/basic/socket-util.c index df3e2c17..9cb0d7f4 100644 --- a/src/libnm-systemd-shared/src/basic/socket-util.c +++ b/src/libnm-systemd-shared/src/basic/socket-util.c @@ -2,10 +2,11 @@ #include "nm-sd-adapt-shared.h" +/* Make sure the net/if.h header is included before any linux/ one */ +#include <net/if.h> #include <arpa/inet.h> #include <errno.h> #include <limits.h> -#include <net/if.h> #include <netdb.h> #include <netinet/ip.h> #include <poll.h> @@ -24,7 +25,7 @@ #include "escape.h" #include "fd-util.h" #include "fileio.h" -#include "format-util.h" +#include "format-ifname.h" #include "io-util.h" #include "log.h" #include "memory-util.h" @@ -458,6 +459,7 @@ int sockaddr_pretty( assert(sa); assert(salen >= sizeof(sa->sa.sa_family)); + assert(ret); switch (sa->sa.sa_family) { @@ -638,7 +640,8 @@ int socknameinfo_pretty(const struct sockaddr *sa, socklen_t salen, char **ret) int r; assert(sa); - assert(salen > sizeof(sa_family_t)); + assert(salen >= sizeof(sa_family_t)); + assert(ret); r = getnameinfo(sa, salen, host, sizeof(host), /* service= */ NULL, /* service_len= */ 0, IDN_FLAGS); if (r != 0) { @@ -652,15 +655,7 @@ int socknameinfo_pretty(const struct sockaddr *sa, socklen_t salen, char **ret) return sockaddr_pretty(sa, salen, /* translate_ipv6= */ true, /* include_port= */ true, ret); } - if (ret) { - char *copy = strdup(host); - if (!copy) - return -ENOMEM; - - *ret = copy; - } - - return 0; + return strdup_to(ret, host); } static const char* const netlink_family_table[] = { @@ -987,6 +982,28 @@ int getpeerpidfd(int fd) { return pidfd; } +int getpeerpidref(int fd, PidRef *ret) { + int r; + + assert(fd >= 0); + assert(ret); + + int pidfd = getpeerpidfd(fd); + if (pidfd < 0) { + if (!ERRNO_IS_NEG_NOT_SUPPORTED(pidfd)) + return pidfd; + + struct ucred ucred; + r = getpeercred(fd, &ucred); + if (r < 0) + return r; + + return pidref_set_pid(ret, ucred.pid); + } + + return pidref_set_pidfd_consume(ret, pidfd); +} + ssize_t send_many_fds_iov_sa( int transport_fd, int *fds_array, size_t n_fds_array, @@ -1124,14 +1141,10 @@ ssize_t receive_many_fds_iov( if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { size_t n = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int); - fds_array = GREEDY_REALLOC(fds_array, n_fds_array + n); - if (!fds_array) { + if (!GREEDY_REALLOC_APPEND(fds_array, n_fds_array, CMSG_TYPED_DATA(cmsg, int), n)) { cmsg_close_all(&mh); return -ENOMEM; } - - memcpy(fds_array + n_fds_array, CMSG_TYPED_DATA(cmsg, int), sizeof(int) * n); - n_fds_array += n; } if (n_fds_array == 0) { @@ -1468,18 +1481,22 @@ int socket_bind_to_ifindex(int fd, int ifindex) { ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags) { ssize_t n; - /* A wrapper around recvmsg() that checks for MSG_CTRUNC, and turns it into an error, in a reasonably - * safe way, closing any SCM_RIGHTS fds in the error path. + /* A wrapper around recvmsg() that checks for MSG_CTRUNC and MSG_TRUNC, and turns them into an error, + * in a reasonably safe way, closing any received fds in the error path. * * Note that unlike our usual coding style this might modify *msg on failure. */ + assert(sockfd >= 0); + assert(msg); + n = recvmsg(sockfd, msg, flags); if (n < 0) return -errno; - if (FLAGS_SET(msg->msg_flags, MSG_CTRUNC)) { + if (FLAGS_SET(msg->msg_flags, MSG_CTRUNC) || + (!FLAGS_SET(flags, MSG_PEEK) && FLAGS_SET(msg->msg_flags, MSG_TRUNC))) { cmsg_close_all(msg); - return -EXFULL; /* a recognizable error code */ + return FLAGS_SET(msg->msg_flags, MSG_CTRUNC) ? -ECHRNG : -EXFULL; } return n; @@ -1781,15 +1798,49 @@ int socket_address_parse_vsock(SocketAddress *ret_address, const char *s) { int vsock_get_local_cid(unsigned *ret) { _cleanup_close_ int vsock_fd = -EBADF; - assert(ret); - vsock_fd = open("/dev/vsock", O_RDONLY|O_CLOEXEC); if (vsock_fd < 0) return log_debug_errno(errno, "Failed to open /dev/vsock: %m"); - if (ioctl(vsock_fd, IOCTL_VM_SOCKETS_GET_LOCAL_CID, ret) < 0) + unsigned tmp; + if (ioctl(vsock_fd, IOCTL_VM_SOCKETS_GET_LOCAL_CID, ret ?: &tmp) < 0) return log_debug_errno(errno, "Failed to query local AF_VSOCK CID: %m"); return 0; } + +int netlink_socket_get_multicast_groups(int fd, size_t *ret_len, uint32_t **ret_groups) { + _cleanup_free_ uint32_t *groups = NULL; + socklen_t len = 0, old_len; + + assert(fd >= 0); + + /* This returns ENOPROTOOPT if the kernel is older than 4.2. */ + + if (getsockopt(fd, SOL_NETLINK, NETLINK_LIST_MEMBERSHIPS, NULL, &len) < 0) + return -errno; + + if (len == 0) + goto finalize; + + groups = new0(uint32_t, len); + if (!groups) + return -ENOMEM; + + old_len = len; + + if (getsockopt(fd, SOL_NETLINK, NETLINK_LIST_MEMBERSHIPS, groups, &len) < 0) + return -errno; + + if (old_len != len) + return -EIO; + +finalize: + if (ret_len) + *ret_len = len; + if (ret_groups) + *ret_groups = TAKE_PTR(groups); + + return 0; +} #endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/socket-util.h b/src/libnm-systemd-shared/src/basic/socket-util.h index 15c7d1c5..b6c38725 100644 --- a/src/libnm-systemd-shared/src/basic/socket-util.h +++ b/src/libnm-systemd-shared/src/basic/socket-util.h @@ -2,15 +2,16 @@ #pragma once #include <inttypes.h> -#include <linux/netlink.h> #include <linux/if_ether.h> #include <linux/if_infiniband.h> #include <linux/if_packet.h> +#include <linux/netlink.h> +#include <sys/socket.h> /* linux/vms_sockets.h requires 'struct sockaddr' */ +#include <linux/vm_sockets.h> #include <netinet/in.h> #include <stdbool.h> #include <stddef.h> #include <string.h> -#include <sys/socket.h> #include <sys/types.h> #include <sys/un.h> @@ -19,6 +20,7 @@ #include "macro.h" #include "missing_network.h" #include "missing_socket.h" +#include "pidref.h" #include "sparse-endian.h" union sockaddr_union { @@ -28,7 +30,7 @@ union sockaddr_union { /* The libc provided version that allocates "enough room" for every protocol */ struct sockaddr_storage storage; - /* Protoctol-specific implementations */ + /* Protocol-specific implementations */ struct sockaddr_in in; struct sockaddr_in6 in6; struct sockaddr_un un; @@ -155,6 +157,7 @@ int getpeercred(int fd, struct ucred *ucred); int getpeersec(int fd, char **ret); int getpeergroups(int fd, gid_t **ret); int getpeerpidfd(int fd); +int getpeerpidref(int fd, PidRef *ret); ssize_t send_many_fds_iov_sa( int transport_fd, @@ -331,7 +334,7 @@ struct timespec_large { /* glibc duplicates timespec/timeval on certain 32-bit arches, once in 32-bit and once in 64-bit. * See __convert_scm_timestamps() in glibc source code. Hence, we need additional buffer space for them - * to prevent from recvmsg_safe() returning -EXFULL. */ + * to prevent truncating control msg (recvmsg() MSG_CTRUNC). */ #define CMSG_SPACE_TIMEVAL \ ((sizeof(struct timeval) == sizeof(struct timeval_large)) ? \ CMSG_SPACE(sizeof(struct timeval)) : \ @@ -393,10 +396,12 @@ int socket_address_parse_unix(SocketAddress *ret_address, const char *s); int socket_address_parse_vsock(SocketAddress *ret_address, const char *s); /* libc's SOMAXCONN is defined to 128 or 4096 (at least on glibc). But actually, the value can be much - * larger. In our codebase we want to set it to the max usually, since noawadays socket memory is properly + * larger. In our codebase we want to set it to the max usually, since nowadays socket memory is properly * tracked by memcg, and hence we don't need to enforce extra limits here. Moreover, the kernel caps it to * /proc/sys/net/core/somaxconn anyway, thus by setting this to unbounded we just make that sysctl file * authoritative. */ #define SOMAXCONN_DELUXE INT_MAX int vsock_get_local_cid(unsigned *ret); + +int netlink_socket_get_multicast_groups(int fd, size_t *ret_len, uint32_t **ret_groups); diff --git a/src/libnm-systemd-shared/src/basic/stat-util.c b/src/libnm-systemd-shared/src/basic/stat-util.c index 4da3845b..ef813e19 100644 --- a/src/libnm-systemd-shared/src/basic/stat-util.c +++ b/src/libnm-systemd-shared/src/basic/stat-util.c @@ -22,6 +22,7 @@ #include "missing_fs.h" #include "missing_magic.h" #include "missing_syscall.h" +#include "mountpoint-util.h" #include "nulstr-util.h" #include "parse-util.h" #include "stat-util.h" @@ -33,6 +34,7 @@ static int verify_stat_at( bool follow, int (*verify_func)(const struct stat *st), bool verify) { + struct stat st; int r; @@ -158,25 +160,9 @@ int dir_is_empty_at(int dir_fd, const char *path, bool ignore_hidden_or_backup) struct dirent *buf; size_t m; - if (path) { - assert(dir_fd >= 0 || dir_fd == AT_FDCWD); - - fd = openat(dir_fd, path, O_RDONLY|O_DIRECTORY|O_CLOEXEC); - if (fd < 0) - return -errno; - } else if (dir_fd == AT_FDCWD) { - fd = open(".", O_RDONLY|O_DIRECTORY|O_CLOEXEC); - if (fd < 0) - return -errno; - } else { - /* Note that DUPing is not enough, as the internal pointer would still be shared and moved - * getedents64(). */ - assert(dir_fd >= 0); - - fd = fd_reopen(dir_fd, O_RDONLY|O_DIRECTORY|O_CLOEXEC); - if (fd < 0) - return fd; - } + fd = xopenat(dir_fd, path, O_DIRECTORY|O_CLOEXEC); + if (fd < 0) + return fd; /* Allocate space for at least 3 full dirents, since every dir has at least two entries ("." + * ".."), and only once we have seen if there's a third we know whether the dir is empty or not. If @@ -231,7 +217,7 @@ int null_or_empty_path_with_root(const char *fn, const char *root) { * When looking under root_dir, we can't expect /dev/ to be mounted, * so let's see if the path is a (possibly dangling) symlink to /dev/null. */ - if (path_equal_ptr(path_startswith(fn, root ?: "/"), "dev/null")) + if (path_equal(path_startswith(fn, root ?: "/"), "dev/null")) return true; r = chase_and_stat(fn, root, CHASE_PREFIX_ROOT, NULL, &st); @@ -241,7 +227,7 @@ int null_or_empty_path_with_root(const char *fn, const char *root) { return null_or_empty(&st); } -static int fd_is_read_only_fs(int fd) { +int fd_is_read_only_fs(int fd) { struct statvfs st; assert(fd >= 0); @@ -271,22 +257,108 @@ int path_is_read_only_fs(const char *path) { return fd_is_read_only_fs(fd); } -#endif /* NM_IGNORED */ int inode_same_at(int fda, const char *filea, int fdb, const char *fileb, int flags) { - struct stat a, b; + struct stat sta, stb; + int r; assert(fda >= 0 || fda == AT_FDCWD); assert(fdb >= 0 || fdb == AT_FDCWD); + assert((flags & ~(AT_EMPTY_PATH|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT)) == 0); + + /* Refuse an unset filea or fileb early unless AT_EMPTY_PATH is set */ + if ((isempty(filea) || isempty(fileb)) && !FLAGS_SET(flags, AT_EMPTY_PATH)) + return -EINVAL; + + /* Shortcut: comparing the same fd with itself means we can return true */ + if (fda >= 0 && fda == fdb && isempty(filea) && isempty(fileb) && FLAGS_SET(flags, AT_SYMLINK_NOFOLLOW)) + return true; - if (fstatat(fda, strempty(filea), &a, flags) < 0) - return log_debug_errno(errno, "Cannot stat %s: %m", filea); + _cleanup_close_ int pin_a = -EBADF, pin_b = -EBADF; + if (!FLAGS_SET(flags, AT_NO_AUTOMOUNT)) { + /* Let's try to use the name_to_handle_at() AT_HANDLE_FID API to identify identical + * inodes. We have to issue multiple calls on the same file for that (first, to acquire the + * FID, and then to check if .st_dev is actually the same). Hence let's pin the inode in + * between via O_PATH, unless we already have an fd for it. */ + + if (!isempty(filea)) { + pin_a = openat(fda, filea, O_PATH|O_CLOEXEC|(FLAGS_SET(flags, AT_SYMLINK_NOFOLLOW) ? O_NOFOLLOW : 0)); + if (pin_a < 0) + return -errno; + + fda = pin_a; + filea = NULL; + flags |= AT_EMPTY_PATH; + } + + if (!isempty(fileb)) { + pin_b = openat(fdb, fileb, O_PATH|O_CLOEXEC|(FLAGS_SET(flags, AT_SYMLINK_NOFOLLOW) ? O_NOFOLLOW : 0)); + if (pin_b < 0) + return -errno; + + fdb = pin_b; + fileb = NULL; + flags |= AT_EMPTY_PATH; + } + + int ntha_flags = (flags & AT_EMPTY_PATH) | (FLAGS_SET(flags, AT_SYMLINK_NOFOLLOW) ? 0 : AT_SYMLINK_FOLLOW); + _cleanup_free_ struct file_handle *ha = NULL, *hb = NULL; + int mntida = -1, mntidb = -1; + + r = name_to_handle_at_try_fid( + fda, + filea, + &ha, + &mntida, + ntha_flags); + if (r < 0) { + if (is_name_to_handle_at_fatal_error(r)) + return r; + + goto fallback; + } + + r = name_to_handle_at_try_fid( + fdb, + fileb, + &hb, + &mntidb, + ntha_flags); + if (r < 0) { + if (is_name_to_handle_at_fatal_error(r)) + return r; + + goto fallback; + } + + /* Now compare the two file handles */ + if (!file_handle_equal(ha, hb)) + return false; + + /* If the file handles are the same and they come from the same mount ID? Great, then we are + * good, they are definitely the same */ + if (mntida == mntidb) + return true; + + /* File handles are the same, they are not on the same mount id. This might either be because + * they are on two entirely different file systems, that just happen to have the same FIDs + * (because they originally where created off the same disk images), or it could be because + * they are located on two distinct bind mounts of the same fs. To check that, let's look at + * .st_rdev of the inode. We simply reuse the fallback codepath for that, since it checks + * exactly that (it checks slightly more, but we don't care.) */ + } + +fallback: + if (fstatat(fda, strempty(filea), &sta, flags) < 0) + return log_debug_errno(errno, "Cannot stat %s: %m", strna(filea)); - if (fstatat(fdb, strempty(fileb), &b, flags) < 0) - return log_debug_errno(errno, "Cannot stat %s: %m", fileb); + if (fstatat(fdb, strempty(fileb), &stb, flags) < 0) + return log_debug_errno(errno, "Cannot stat %s: %m", strna(fileb)); - return stat_inode_same(&a, &b); + return stat_inode_same(&sta, &stb); } +#endif /* NM_IGNORED */ + bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) { assert(s); @@ -369,8 +441,7 @@ bool stat_inode_same(const struct stat *a, const struct stat *b) { /* Returns if the specified stat structure references the same (though possibly modified) inode. Does * a thorough check, comparing inode nr, backing device and if the inode is still of the same type. */ - return a && b && - (a->st_mode & S_IFMT) != 0 && /* We use the check for .st_mode if the structure was ever initialized */ + return stat_is_set(a) && stat_is_set(b) && ((a->st_mode ^ b->st_mode) & S_IFMT) == 0 && /* same inode type */ a->st_dev == b->st_dev && a->st_ino == b->st_ino; @@ -399,9 +470,8 @@ bool statx_inode_same(const struct statx *a, const struct statx *b) { /* Same as stat_inode_same() but for struct statx */ - return a && b && + return statx_is_set(a) && statx_is_set(b) && FLAGS_SET(a->stx_mask, STATX_TYPE|STATX_INO) && FLAGS_SET(b->stx_mask, STATX_TYPE|STATX_INO) && - (a->stx_mode & S_IFMT) != 0 && ((a->stx_mode ^ b->stx_mode) & S_IFMT) == 0 && a->stx_dev_major == b->stx_dev_major && a->stx_dev_minor == b->stx_dev_minor && @@ -409,7 +479,7 @@ bool statx_inode_same(const struct statx *a, const struct statx *b) { } bool statx_mount_same(const struct new_statx *a, const struct new_statx *b) { - if (!a || !b) + if (!new_statx_is_set(a) || !new_statx_is_set(b)) return false; /* if we have the mount ID, that's all we need */ @@ -545,6 +615,8 @@ const char* inode_type_to_string(mode_t m) { return "sock"; } + /* Note anonymous inodes in the kernel will have a zero type. Hence fstat() of an eventfd() will + * return an .st_mode where we'll return NULL here! */ return NULL; } diff --git a/src/libnm-systemd-shared/src/basic/stat-util.h b/src/libnm-systemd-shared/src/basic/stat-util.h index 7eb951a7..17fb520f 100644 --- a/src/libnm-systemd-shared/src/basic/stat-util.h +++ b/src/libnm-systemd-shared/src/basic/stat-util.h @@ -9,6 +9,7 @@ #include <sys/types.h> #include <sys/vfs.h> +#include "fs-util.h" #include "macro.h" #include "missing_stat.h" #include "siphash24.h" @@ -44,13 +45,16 @@ static inline int null_or_empty_path(const char *fn) { return null_or_empty_path_with_root(fn, NULL); } +int fd_is_read_only_fs(int fd); int path_is_read_only_fs(const char *path); int inode_same_at(int fda, const char *filea, int fdb, const char *fileb, int flags); - static inline int inode_same(const char *filea, const char *fileb, int flags) { return inode_same_at(AT_FDCWD, filea, AT_FDCWD, fileb, flags); } +static inline int fd_inode_same(int fda, int fdb) { + return inode_same_at(fda, NULL, fdb, NULL, AT_EMPTY_PATH); +} /* The .f_type field of struct statfs is really weird defined on * different archs. Let's give its type a name. */ @@ -126,3 +130,20 @@ extern const struct hash_ops inode_hash_ops; const char* inode_type_to_string(mode_t m); mode_t inode_type_from_string(const char *s); + +/* Macros that check whether the stat/statx structures have been initialized already. For "struct stat" we + * use a check for .st_dev being non-zero, since the kernel unconditionally fills that in, mapping the file + * to its originating superblock, regardless if the fs is block based or virtual (we also check for .st_mode + * being MODE_INVALID, since we use that as an invalid marker for separate mode_t fields). For "struct statx" + * we use the .stx_mask field, which must be non-zero if any of the fields have already been initialized. */ +static inline bool stat_is_set(const struct stat *st) { + return st && st->st_dev != 0 && st->st_mode != MODE_INVALID; +} +#if 0 /* NM_IGNORED */ +static inline bool statx_is_set(const struct statx *sx) { + return sx && sx->stx_mask != 0; +} +static inline bool new_statx_is_set(const struct new_statx *sx) { + return sx && sx->stx_mask != 0; +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/stdio-util.h b/src/libnm-systemd-shared/src/basic/stdio-util.h index d0b25fdf..c35e6655 100644 --- a/src/libnm-systemd-shared/src/basic/stdio-util.h +++ b/src/libnm-systemd-shared/src/basic/stdio-util.h @@ -11,14 +11,12 @@ #include "macro.h" _printf_(3, 4) -static inline char *snprintf_ok(char *buf, size_t len, const char *format, ...) { +static inline char* snprintf_ok(char *buf, size_t len, const char *format, ...) { va_list ap; int r; va_start(ap, format); - DISABLE_WARNING_FORMAT_NONLITERAL; r = vsnprintf(buf, len, format, ap); - REENABLE_WARNING; va_end(ap); return r >= 0 && (size_t) r < len ? buf : NULL; diff --git a/src/libnm-systemd-shared/src/basic/string-table.h b/src/libnm-systemd-shared/src/basic/string-table.h index 3be70dfa..83891eeb 100644 --- a/src/libnm-systemd-shared/src/basic/string-table.h +++ b/src/libnm-systemd-shared/src/basic/string-table.h @@ -15,7 +15,7 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k /* For basic lookup tables with strictly enumerated entries */ #define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \ - scope const char *name##_to_string(type i) { \ + scope const char* name##_to_string(type i) { \ if (i < 0 || i >= (type) ELEMENTSOF(name##_table)) \ return NULL; \ return name##_table[i]; \ @@ -47,10 +47,8 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k s = strdup(name##_table[i]); \ if (!s) \ return -ENOMEM; \ - } else { \ - if (asprintf(&s, "%i", i) < 0) \ - return -ENOMEM; \ - } \ + } else if (asprintf(&s, "%i", i) < 0) \ + return -ENOMEM; \ *str = s; \ return 0; \ } @@ -103,7 +101,7 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,static) #define DUMP_STRING_TABLE(name,type,max) \ - do { \ + ({ \ flockfile(stdout); \ for (type _k = 0; _k < (max); _k++) { \ const char *_t; \ @@ -114,4 +112,5 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k fputc_unlocked('\n', stdout); \ } \ funlockfile(stdout); \ - } while (false) + 0; \ + }) diff --git a/src/libnm-systemd-shared/src/basic/string-util.c b/src/libnm-systemd-shared/src/basic/string-util.c index 59e65918..6a06594a 100644 --- a/src/libnm-systemd-shared/src/basic/string-util.c +++ b/src/libnm-systemd-shared/src/basic/string-util.c @@ -13,6 +13,7 @@ #include "extract-word.h" #include "fd-util.h" #include "fileio.h" +#include "glyph-util.h" #include "gunicode.h" #include "locale-util.h" #include "macro.h" @@ -25,40 +26,29 @@ #include "utf8.h" char* first_word(const char *s, const char *word) { - size_t sl, wl; - const char *p; - assert(s); assert(word); - /* Checks if the string starts with the specified word, either - * followed by NUL or by whitespace. Returns a pointer to the - * NUL or the first character after the whitespace. */ - - sl = strlen(s); - wl = strlen(word); - - if (sl < wl) - return NULL; + /* Checks if the string starts with the specified word, either followed by NUL or by whitespace. + * Returns a pointer to the NUL or the first character after the whitespace. */ - if (wl == 0) + if (isempty(word)) return (char*) s; - if (memcmp(s, word, wl) != 0) + const char *p = startswith(s, word); + if (!p) return NULL; - - p = s + wl; - if (*p == 0) + if (*p == '\0') return (char*) p; - if (!strchr(WHITESPACE, *p)) + const char *nw = skip_leading_chars(p, WHITESPACE); + if (p == nw) return NULL; - p += strspn(p, WHITESPACE); - return (char*) p; + return (char*) nw; } -char *strnappend(const char *s, const char *suffix, size_t b) { +char* strnappend(const char *s, const char *suffix, size_t b) { size_t a; char *r; @@ -89,40 +79,8 @@ char *strnappend(const char *s, const char *suffix, size_t b) { return r; } -char *strjoin_real(const char *x, ...) { - va_list ap; - size_t l = 1; - char *r, *p; - - va_start(ap, x); - for (const char *t = x; t; t = va_arg(ap, const char *)) { - size_t n; - - n = strlen(t); - if (n > SIZE_MAX - l) { - va_end(ap); - return NULL; - } - l += n; - } - va_end(ap); - - p = r = new(char, l); - if (!r) - return NULL; - - va_start(ap, x); - for (const char *t = x; t; t = va_arg(ap, const char *)) - p = stpcpy(p, t); - va_end(ap); - - *p = 0; - - return r; -} - #if 0 /* NM_IGNORED */ -char *strstrip(char *s) { +char* strstrip(char *s) { if (!s) return NULL; @@ -131,7 +89,7 @@ char *strstrip(char *s) { return delete_trailing_chars(skip_leading_chars(s, WHITESPACE), WHITESPACE); } -char *delete_chars(char *s, const char *bad) { +char* delete_chars(char *s, const char *bad) { char *f, *t; /* Drops all specified bad characters, regardless where in the string */ @@ -154,7 +112,7 @@ char *delete_chars(char *s, const char *bad) { return s; } -char *delete_trailing_chars(char *s, const char *bad) { +char* delete_trailing_chars(char *s, const char *bad) { char *c = s; /* Drops all specified bad characters, at the end of the string */ @@ -175,7 +133,7 @@ char *delete_trailing_chars(char *s, const char *bad) { } #endif /* NM_IGNORED */ -char *truncate_nl_full(char *s, size_t *ret_len) { +char* truncate_nl_full(char *s, size_t *ret_len) { size_t n; assert(s); @@ -203,7 +161,7 @@ char ascii_toupper(char x) { return x; } -char *ascii_strlower(char *t) { +char* ascii_strlower(char *t) { assert(t); for (char *p = t; *p; p++) @@ -212,7 +170,7 @@ char *ascii_strlower(char *t) { return t; } -char *ascii_strupper(char *t) { +char* ascii_strupper(char *t) { assert(t); for (char *p = t; *p; p++) @@ -221,7 +179,7 @@ char *ascii_strupper(char *t) { return t; } -char *ascii_strlower_n(char *t, size_t n) { +char* ascii_strlower_n(char *t, size_t n) { if (n <= 0) return t; @@ -287,16 +245,9 @@ bool string_has_cc(const char *p, const char *ok) { #if 0 /* NM_IGNORED */ static int write_ellipsis(char *buf, bool unicode) { - if (unicode || is_locale_utf8()) { - buf[0] = 0xe2; /* tri-dot ellipsis: … */ - buf[1] = 0x80; - buf[2] = 0xa6; - } else { - buf[0] = '.'; - buf[1] = '.'; - buf[2] = '.'; - } - + const char *s = special_glyph_full(SPECIAL_GLYPH_ELLIPSIS, unicode); + assert(strlen(s) == 3); + memcpy(buf, s, 3); return 3; } @@ -403,8 +354,7 @@ static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_le x = ((new_length - need_space) * percent + 50) / 100; assert(x <= new_length - need_space); - memcpy(t, s, x); - write_ellipsis(t + x, false); + write_ellipsis(mempcpy(t, s, x), /* unicode = */ false); suffix_len = new_length - x - need_space; memcpy(t + x + 3, s + old_length - suffix_len, suffix_len); *(t + x + 3 + suffix_len) = '\0'; @@ -412,7 +362,7 @@ static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_le return t; } -char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) { +char* ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) { size_t x, k, len, len2; const char *i, *j; int r; @@ -525,13 +475,8 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne if (!e) return NULL; - /* - printf("old_length=%zu new_length=%zu x=%zu len=%zu len2=%zu k=%zu\n", - old_length, new_length, x, len, len2, k); - */ - memcpy_safe(e, s, len); - write_ellipsis(e + len, true); + write_ellipsis(e + len, /* unicode = */ true); char *dst = e + len + 3; @@ -552,7 +497,7 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne return e; } -char *cellescape(char *buf, size_t len, const char *s) { +char* cellescape(char *buf, size_t len, const char *s) { /* Escape and ellipsize s into buffer buf of size len. Only non-control ASCII * characters are copied as they are, everything else is escaped. The result * is different then if escaping and ellipsization was performed in two @@ -567,7 +512,9 @@ char *cellescape(char *buf, size_t len, const char *s) { size_t i = 0, last_char_width[4] = {}, k = 0; + assert(buf); assert(len > 0); /* at least a terminating NUL */ + assert(s); for (;;) { char four[4]; @@ -608,7 +555,7 @@ char *cellescape(char *buf, size_t len, const char *s) { } if (i + 4 <= len) /* yay, enough space */ - i += write_ellipsis(buf + i, false); + i += write_ellipsis(buf + i, /* unicode = */ false); else if (i + 3 <= len) { /* only space for ".." */ buf[i++] = '.'; buf[i++] = '.'; @@ -617,7 +564,7 @@ char *cellescape(char *buf, size_t len, const char *s) { else assert(i + 1 <= len); - done: +done: buf[i] = '\0'; return buf; } @@ -657,7 +604,7 @@ int strgrowpad0(char **s, size_t l) { } #endif /* NM_IGNORED */ -char *strreplace(const char *text, const char *old_string, const char *new_string) { +char* strreplace(const char *text, const char *old_string, const char *new_string) { size_t l, old_len, new_len; char *t, *ret = NULL; const char *f; @@ -720,13 +667,14 @@ static void advance_offsets( shift[1] += size; } -char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) { +char* strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) { const char *begin = NULL; enum { STATE_OTHER, STATE_ESCAPE, STATE_CSI, - STATE_CSO, + STATE_OSC, + STATE_OSC_CLOSING, } state = STATE_OTHER; _cleanup_(memstream_done) MemStream m = {}; size_t isz, shift[2] = {}, n_carriage_returns = 0; @@ -739,7 +687,7 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) { * * 1. Replaces TABs by 8 spaces * 2. Strips ANSI color sequences (a subset of CSI), i.e. ESC '[' … 'm' sequences - * 3. Strips ANSI operating system sequences (CSO), i.e. ESC ']' … BEL sequences + * 3. Strips ANSI operating system sequences (OSC), i.e. ESC ']' … ST sequences * 4. Strip trailing \r characters (since they would "move the cursor", but have no * other effect). * @@ -747,7 +695,7 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) { * are any other special characters. Truncated ANSI sequences are left-as is too. This call is * supposed to suppress the most basic formatting noise, but nothing else. * - * Why care for CSO sequences? Well, to undo what terminal_urlify() and friends generate. */ + * Why care for OSC sequences? Well, to undo what terminal_urlify() and friends generate. */ isz = _isz ? *_isz : strlen(*ibuf); @@ -759,10 +707,12 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) { for (const char *i = *ibuf; i < *ibuf + isz + 1; i++) { + bool eot = i >= *ibuf + isz; + switch (state) { case STATE_OTHER: - if (i >= *ibuf + isz) /* EOT */ + if (eot) break; if (*i == '\r') { @@ -787,15 +737,15 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) { case STATE_ESCAPE: assert(n_carriage_returns == 0); - if (i >= *ibuf + isz) { /* EOT */ + if (eot) { fputc('\x1B', f); advance_offsets(i - *ibuf, highlight, shift, 1); break; } else if (*i == '[') { /* ANSI CSI */ state = STATE_CSI; begin = i + 1; - } else if (*i == ']') { /* ANSI CSO */ - state = STATE_CSO; + } else if (*i == ']') { /* ANSI OSC */ + state = STATE_OSC; begin = i + 1; } else { fputc('\x1B', f); @@ -809,8 +759,7 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) { case STATE_CSI: assert(n_carriage_returns == 0); - if (i >= *ibuf + isz || /* EOT … */ - !strchr("01234567890;m", *i)) { /* … or invalid chars in sequence */ + if (eot || !strchr("01234567890;m", *i)) { /* EOT or invalid chars in sequence */ fputc('\x1B', f); fputc('[', f); advance_offsets(i - *ibuf, highlight, shift, 2); @@ -821,17 +770,33 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) { break; - case STATE_CSO: + case STATE_OSC: assert(n_carriage_returns == 0); - if (i >= *ibuf + isz || /* EOT … */ - (*i != '\a' && (uint8_t) *i < 32U) || (uint8_t) *i > 126U) { /* … or invalid chars in sequence */ + /* There are three kinds of OSC terminators: \x07, \x1b\x5c or \x9c. We only support + * the first two, because the last one is a valid UTF-8 codepoint and hence creates + * an ambiguity (many Terminal emulators refuse to support it as well). */ + if (eot || (!IN_SET(*i, '\x07', '\x1b') && !osc_char_is_valid(*i))) { /* EOT or invalid chars in sequence */ fputc('\x1B', f); fputc(']', f); advance_offsets(i - *ibuf, highlight, shift, 2); state = STATE_OTHER; i = begin-1; - } else if (*i == '\a') + } else if (*i == '\x07') /* Single character ST */ + state = STATE_OTHER; + else if (*i == '\x1B') + state = STATE_OSC_CLOSING; + + break; + + case STATE_OSC_CLOSING: + if (eot || *i != '\x5c') { /* EOT or incomplete two-byte ST in sequence */ + fputc('\x1B', f); + fputc(']', f); + advance_offsets(i - *ibuf, highlight, shift, 2); + state = STATE_OTHER; + i = begin-1; + } else if (*i == '\x5c') state = STATE_OTHER; break; @@ -853,13 +818,15 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) { } #endif /* NM_IGNORED */ -char *strextend_with_separator_internal(char **x, const char *separator, ...) { +char* strextend_with_separator_internal(char **x, const char *separator, ...) { + _cleanup_free_ char *buffer = NULL; size_t f, l, l_separator; bool need_separator; char *nr, *p; va_list ap; - assert(x); + if (!x) + x = &buffer; l = f = strlen_ptr(*x); @@ -867,13 +834,14 @@ char *strextend_with_separator_internal(char **x, const char *separator, ...) { l_separator = strlen_ptr(separator); va_start(ap, separator); - for (;;) { - const char *t; + for (const char *t;;) { size_t n; t = va_arg(ap, const char *); if (!t) break; + if (t == POINTER_MAX) + continue; n = strlen(t); @@ -906,6 +874,8 @@ char *strextend_with_separator_internal(char **x, const char *separator, ...) { t = va_arg(ap, const char *); if (!t) break; + if (t == POINTER_MAX) + continue; if (need_separator && separator) p = stpcpy(p, separator); @@ -917,9 +887,13 @@ char *strextend_with_separator_internal(char **x, const char *separator, ...) { va_end(ap); assert(p == nr + l); - *p = 0; + /* If no buffer to extend was passed in return the start of the buffer */ + if (buffer) + return TAKE_PTR(buffer); + + /* Otherwise we extended the buffer: return the end */ return p; } @@ -1004,12 +978,12 @@ int strextendf_with_separator(char **x, const char *separator, const char *forma return 0; oom: - /* truncate the bytes added after the first vsnprintf() attempt again */ + /* truncate the bytes added after memcpy_safe() again */ (*x)[m] = 0; return -ENOMEM; } -char *strextendn(char **x, const char *s, size_t l) { +char* strextendn(char **x, const char *s, size_t l) { assert(x); assert(s || l == 0); @@ -1036,7 +1010,7 @@ char *strextendn(char **x, const char *s, size_t l) { return *x; } -char *strrep(const char *s, unsigned n) { +char* strrep(const char *s, unsigned n) { char *r, *p; size_t l; @@ -1054,34 +1028,26 @@ char *strrep(const char *s, unsigned n) { return r; } -int split_pair(const char *s, const char *sep, char **l, char **r) { - char *x, *a, *b; - +int split_pair(const char *s, const char *sep, char **ret_first, char **ret_second) { assert(s); - assert(sep); - assert(l); - assert(r); + assert(!isempty(sep)); + assert(ret_first); + assert(ret_second); - if (isempty(sep)) - return -EINVAL; - - x = strstr(s, sep); + const char *x = strstr(s, sep); if (!x) return -EINVAL; - a = strndup(s, x - s); + _cleanup_free_ char *a = strndup(s, x - s); if (!a) return -ENOMEM; - b = strdup(x + strlen(sep)); - if (!b) { - free(a); + _cleanup_free_ char *b = strdup(x + strlen(sep)); + if (!b) return -ENOMEM; - } - - *l = a; - *r = b; + *ret_first = TAKE_PTR(a); + *ret_second = TAKE_PTR(b); return 0; } @@ -1134,6 +1100,24 @@ int free_and_strndup(char **p, const char *s, size_t l) { return 1; } +int strdup_to_full(char **ret, const char *src) { + if (!src) { + if (ret) + *ret = NULL; + + return 0; + } else { + if (ret) { + char *t = strdup(src); + if (!t) + return -ENOMEM; + *ret = t; + } + + return 1; + } +}; + bool string_is_safe(const char *p) { if (!p) return false; @@ -1244,54 +1228,31 @@ int string_extract_line(const char *s, size_t i, char **ret) { return -ENOMEM; *ret = m; - return !isempty(q + 1); /* more coming? */ - } else { - if (p == s) - *ret = NULL; /* Just use the input string */ - else { - char *m; - - m = strdup(p); - if (!m) - return -ENOMEM; - - *ret = m; - } - - return 0; /* The end */ - } + return !isempty(q + 1); /* More coming? */ + } else + /* Tell the caller to use the input string if equal */ + return strdup_to(ret, p != s ? p : NULL); } - if (!q) { - char *m; - + if (!q) /* No more lines, return empty line */ - - m = strdup(""); - if (!m) - return -ENOMEM; - - *ret = m; - return 0; /* The end */ - } + return strdup_to(ret, ""); p = q + 1; c++; } } -int string_contains_word_strv(const char *string, const char *separators, char **words, const char **ret_word) { - /* In the default mode with no separators specified, we split on whitespace and - * don't coalesce separators. */ +int string_contains_word_strv(const char *string, const char *separators, char * const *words, const char **ret_word) { + /* In the default mode with no separators specified, we split on whitespace and coalesce separators. */ const ExtractFlags flags = separators ? EXTRACT_DONT_COALESCE_SEPARATORS : 0; - const char *found = NULL; + int r; - for (const char *p = string;;) { + for (;;) { _cleanup_free_ char *w = NULL; - int r; - r = extract_first_word(&p, &w, separators, flags); + r = extract_first_word(&string, &w, separators, flags); if (r < 0) return r; if (r == 0) @@ -1324,7 +1285,7 @@ bool streq_skip_trailing_chars(const char *s1, const char *s2, const char *ok) { } #endif /* NM_IGNORED */ -char *string_replace_char(char *str, char old_char, char new_char) { +char* string_replace_char(char *str, char old_char, char new_char) { assert(str); assert(old_char != '\0'); assert(new_char != '\0'); @@ -1395,14 +1356,14 @@ size_t strspn_from_end(const char *str, const char *accept) { } #if 0 /* NM_IGNORED */ -char *strdupspn(const char *a, const char *accept) { +char* strdupspn(const char *a, const char *accept) { if (isempty(a) || isempty(accept)) return strdup(""); return strndup(a, strspn(a, accept)); } -char *strdupcspn(const char *a, const char *reject) { +char* strdupcspn(const char *a, const char *reject) { if (isempty(a)) return strdup(""); if (isempty(reject)) @@ -1411,7 +1372,7 @@ char *strdupcspn(const char *a, const char *reject) { return strndup(a, strcspn(a, reject)); } -char *find_line_startswith(const char *haystack, const char *needle) { +char* find_line_startswith(const char *haystack, const char *needle) { char *p; assert(haystack); @@ -1523,7 +1484,7 @@ ssize_t strlevenshtein(const char *x, const char *y) { return t1[yl]; } -char *strrstr(const char *haystack, const char *needle) { +char* strrstr(const char *haystack, const char *needle) { /* Like strstr() but returns the last rather than the first occurrence of "needle" in "haystack". */ if (!haystack || !needle) diff --git a/src/libnm-systemd-shared/src/basic/string-util.h b/src/libnm-systemd-shared/src/basic/string-util.h index e162765a..1bcb1c40 100644 --- a/src/libnm-systemd-shared/src/basic/string-util.h +++ b/src/libnm-systemd-shared/src/basic/string-util.h @@ -8,6 +8,7 @@ #include "alloc-util.h" #include "macro.h" #include "string-util-fundamental.h" +#include "utf8.h" /* What is interpreted as whitespace? */ #define WHITESPACE " \t\n\r" @@ -32,7 +33,7 @@ static inline char* strstr_ptr(const char *haystack, const char *needle) { return strstr(haystack, needle); } -static inline char *strstrafter(const char *haystack, const char *needle) { +static inline char* strstrafter(const char *haystack, const char *needle) { char *p; /* Returns NULL if not found, or pointer to first character after needle if found */ @@ -48,7 +49,7 @@ static inline const char* strnull(const char *s) { return s ?: "(null)"; } -static inline const char *strna(const char *s) { +static inline const char* strna(const char *s) { return s ?: "n/a"; } @@ -80,11 +81,11 @@ static inline const char* enabled_disabled(bool b) { (typeof(p)) (isempty(_p) ? NULL : _p); \ }) -static inline const char *empty_to_na(const char *p) { +static inline const char* empty_to_na(const char *p) { return isempty(p) ? "n/a" : p; } -static inline const char *empty_to_dash(const char *str) { +static inline const char* empty_to_dash(const char *str) { return isempty(str) ? "-" : str; } @@ -94,7 +95,7 @@ static inline bool empty_or_dash(const char *str) { (str[0] == '-' && str[1] == 0); } -static inline const char *empty_or_dash_to_null(const char *p) { +static inline const char* empty_or_dash_to_null(const char *p) { return empty_or_dash(p) ? NULL : p; } #define empty_or_dash_to_null(p) \ @@ -103,12 +104,11 @@ static inline const char *empty_or_dash_to_null(const char *p) { (typeof(p)) (empty_or_dash(_p) ? NULL : _p); \ }) -char *first_word(const char *s, const char *word) _pure_; +char* first_word(const char *s, const char *word) _pure_; -char *strnappend(const char *s, const char *suffix, size_t length); +char* strnappend(const char *s, const char *suffix, size_t length); -char *strjoin_real(const char *x, ...) _sentinel_; -#define strjoin(a, ...) strjoin_real((a), __VA_ARGS__, NULL) +#define strjoin(a, ...) strextend_with_separator_internal(NULL, NULL, a, __VA_ARGS__, NULL) #define strjoina(a, ...) \ ({ \ @@ -125,15 +125,15 @@ char *strjoin_real(const char *x, ...) _sentinel_; _d_; \ }) -char *strstrip(char *s); -char *delete_chars(char *s, const char *bad); -char *delete_trailing_chars(char *s, const char *bad); -char *truncate_nl_full(char *s, size_t *ret_len); -static inline char *truncate_nl(char *s) { +char* strstrip(char *s); +char* delete_chars(char *s, const char *bad); +char* delete_trailing_chars(char *s, const char *bad); +char* truncate_nl_full(char *s, size_t *ret_len); +static inline char* truncate_nl(char *s) { return truncate_nl_full(s, NULL); } -static inline char *skip_leading_chars(const char *s, const char *bad) { +static inline char* skip_leading_chars(const char *s, const char *bad) { if (!s) return NULL; @@ -144,18 +144,18 @@ static inline char *skip_leading_chars(const char *s, const char *bad) { } char ascii_tolower(char x); -char *ascii_strlower(char *s); -char *ascii_strlower_n(char *s, size_t n); +char* ascii_strlower(char *s); +char* ascii_strlower_n(char *s, size_t n); char ascii_toupper(char x); -char *ascii_strupper(char *s); +char* ascii_strupper(char *s); int ascii_strcasecmp_n(const char *a, const char *b, size_t n); int ascii_strcasecmp_nn(const char *a, size_t n, const char *b, size_t m); bool chars_intersect(const char *a, const char *b) _pure_; -static inline bool _pure_ in_charset(const char *s, const char* charset) { +static inline bool _pure_ in_charset(const char *s, const char *charset) { assert(s); assert(charset); return s[strspn(s, charset)] == '\0'; @@ -171,12 +171,12 @@ static inline bool char_is_cc(char p) { } bool string_has_cc(const char *p, const char *ok) _pure_; -char *ellipsize_mem(const char *s, size_t old_length_bytes, size_t new_length_columns, unsigned percent); -static inline char *ellipsize(const char *s, size_t length, unsigned percent) { +char* ellipsize_mem(const char *s, size_t old_length_bytes, size_t new_length_columns, unsigned percent); +static inline char* ellipsize(const char *s, size_t length, unsigned percent) { return ellipsize_mem(s, strlen(s), length, percent); } -char *cellescape(char *buf, size_t len, const char *s); +char* cellescape(char *buf, size_t len, const char *s); /* This limit is arbitrary, enough to give some idea what the string contains */ #define CELLESCAPE_DEFAULT_LENGTH 64 @@ -185,33 +185,35 @@ char* strshorten(char *s, size_t l); int strgrowpad0(char **s, size_t l); -char *strreplace(const char *text, const char *old_string, const char *new_string); +char* strreplace(const char *text, const char *old_string, const char *new_string); -char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]); +char* strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]); -char *strextend_with_separator_internal(char **x, const char *separator, ...) _sentinel_; +char* strextend_with_separator_internal(char **x, const char *separator, ...) _sentinel_; #define strextend_with_separator(x, separator, ...) strextend_with_separator_internal(x, separator, __VA_ARGS__, NULL) #define strextend(x, ...) strextend_with_separator_internal(x, NULL, __VA_ARGS__, NULL) -char *strextendn(char **x, const char *s, size_t l); +char* strextendn(char **x, const char *s, size_t l); int strextendf_with_separator(char **x, const char *separator, const char *format, ...) _printf_(3,4); #define strextendf(x, ...) strextendf_with_separator(x, NULL, __VA_ARGS__) -char *strrep(const char *s, unsigned n); +char* strrep(const char *s, unsigned n); -#define strrepa(s, n) \ - ({ \ - char *_d_, *_p_; \ - size_t _len_ = strlen(s) * n; \ - _p_ = _d_ = newa(char, _len_ + 1); \ - for (unsigned _i_ = 0; _i_ < n; _i_++) \ - _p_ = stpcpy(_p_, s); \ - *_p_ = 0; \ - _d_; \ +#define strrepa(s, n) \ + ({ \ + const char *_sss_ = (s); \ + size_t _nnn_ = (n), _len_ = strlen(_sss_); \ + assert_se(MUL_ASSIGN_SAFE(&_len_, _nnn_)); \ + char *_d_, *_p_; \ + _p_ = _d_ = newa(char, _len_ + 1); \ + for (size_t _i_ = 0; _i_ < _nnn_; _i_++) \ + _p_ = stpcpy(_p_, _sss_); \ + *_p_ = 0; \ + _d_; \ }) -int split_pair(const char *s, const char *sep, char **l, char **r); +int split_pair(const char *s, const char *sep, char **ret_first, char **ret_second); int free_and_strdup(char **p, const char *s); static inline int free_and_strdup_warn(char **p, const char *s) { @@ -224,7 +226,16 @@ static inline int free_and_strdup_warn(char **p, const char *s) { } int free_and_strndup(char **p, const char *s, size_t l); +int strdup_to_full(char **ret, const char *src); +static inline int strdup_to(char **ret, const char *src) { + int r = strdup_to_full(ASSERT_PTR(ret), src); + return r < 0 ? r : 0; /* Suppress return value of 1. */ +} + bool string_is_safe(const char *p) _pure_; +static inline bool string_is_safe_ascii(const char *p) { + return ascii_is_valid(p) && string_is_safe(p); +} DISABLE_WARNING_STRINGOP_TRUNCATION; static inline void strncpy_exact(char *buf, const char *src, size_t buf_len) { @@ -235,7 +246,7 @@ REENABLE_WARNING; /* Like startswith_no_case(), but operates on arbitrary memory blocks. * It works only for ASCII strings. */ -static inline void *memory_startswith_no_case(const void *p, size_t sz, const char *token) { +static inline void* memory_startswith_no_case(const void *p, size_t sz, const char *token) { assert(token); size_t n = strlen(token); @@ -265,14 +276,14 @@ char* string_erase(char *x); int string_truncate_lines(const char *s, size_t n_lines, char **ret); int string_extract_line(const char *s, size_t i, char **ret); -int string_contains_word_strv(const char *string, const char *separators, char **words, const char **ret_word); +int string_contains_word_strv(const char *string, const char *separators, char * const *words, const char **ret_word); static inline int string_contains_word(const char *string, const char *separators, const char *word) { return string_contains_word_strv(string, separators, STRV_MAKE(word), NULL); } bool streq_skip_trailing_chars(const char *s1, const char *s2, const char *ok); -char *string_replace_char(char *str, char old_char, char new_char); +char* string_replace_char(char *str, char old_char, char new_char); typedef enum MakeCStringMode { MAKE_CSTRING_REFUSE_TRAILING_NUL, @@ -286,10 +297,10 @@ int make_cstring(const char *s, size_t n, MakeCStringMode mode, char **ret); size_t strspn_from_end(const char *str, const char *accept); -char *strdupspn(const char *a, const char *accept); -char *strdupcspn(const char *a, const char *reject); +char* strdupspn(const char *a, const char *accept); +char* strdupcspn(const char *a, const char *reject); -char *find_line_startswith(const char *haystack, const char *needle); +char* find_line_startswith(const char *haystack, const char *needle); bool version_is_valid(const char *s); @@ -297,25 +308,4 @@ bool version_is_valid_versionspec(const char *s); ssize_t strlevenshtein(const char *x, const char *y); -static inline int strdup_or_null(const char *s, char **ret) { - char *c; - - assert(ret); - - /* This is a lot like strdup(), but is happy with NULL strings, and does not treat that as error, but - * copies the NULL value. */ - - if (!s) { - *ret = NULL; - return 0; - } - - c = strdup(s); - if (!c) - return -ENOMEM; - - *ret = c; - return 1; -} - -char *strrstr(const char *haystack, const char *needle); +char* strrstr(const char *haystack, const char *needle); diff --git a/src/libnm-systemd-shared/src/basic/strv.c b/src/libnm-systemd-shared/src/basic/strv.c index ed02b481..38466696 100644 --- a/src/libnm-systemd-shared/src/basic/strv.c +++ b/src/libnm-systemd-shared/src/basic/strv.c @@ -13,11 +13,13 @@ #include "escape.h" #include "extract-word.h" #include "fileio.h" +#include "gunicode.h" #include "memory-util.h" #include "nulstr-util.h" #include "sort-util.h" #include "string-util.h" #include "strv.h" +#include "utf8.h" char* strv_find(char * const *l, const char *name) { assert(name); @@ -66,6 +68,68 @@ char* strv_find_startswith(char * const *l, const char *name) { return NULL; } +static char* strv_find_closest_prefix(char * const *l, const char *name) { + size_t best_distance = SIZE_MAX; + char *best = NULL; + + assert(name); + + STRV_FOREACH(s, l) { + char *e = startswith(*s, name); + if (!e) + continue; + + size_t n = strlen(e); + if (n < best_distance) { + best_distance = n; + best = *s; + } + } + + return best; +} + +static char* strv_find_closest_by_levenshtein(char * const *l, const char *name) { + ssize_t best_distance = SSIZE_MAX; + char *best = NULL; + + assert(name); + + STRV_FOREACH(i, l) { + ssize_t distance; + + distance = strlevenshtein(*i, name); + if (distance < 0) { + log_debug_errno(distance, "Failed to determine Levenshtein distance between %s and %s: %m", *i, name); + return NULL; + } + + if (distance > 5) /* If the distance is just too far off, don't make a bad suggestion */ + continue; + + if (distance < best_distance) { + best_distance = distance; + best = *i; + } + } + + return best; +} + +char* strv_find_closest(char * const *l, const char *name) { + assert(name); + + /* Be more helpful to the user, and give a hint what the user might have wanted to type. We search + * with two mechanisms: a simple prefix match and – if that didn't yield results –, a Levenshtein + * word distance based match. */ + + char *found = strv_find_closest_prefix(l, name); + if (found) + return found; + + return strv_find_closest_by_levenshtein(l, name); +} + char* strv_find_first_field(char * const *needles, char * const *haystack) { STRV_FOREACH(k, needles) { char *value = strv_env_pairs_get((char **)haystack, *k); @@ -202,20 +266,18 @@ char** strv_new_internal(const char *x, ...) { int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates) { size_t p, q, i = 0; - char **t; assert(a); - if (strv_isempty(b)) + q = strv_length(b); + if (q == 0) return 0; p = strv_length(*a); - q = strv_length(b); - if (p >= SIZE_MAX - q) return -ENOMEM; - t = reallocarray(*a, GREEDY_ALLOC_ROUND_UP(p + q + 1), sizeof(char *)); + char **t = reallocarray(*a, GREEDY_ALLOC_ROUND_UP(p + q + 1), sizeof(char *)); if (!t) return -ENOMEM; @@ -244,22 +306,78 @@ rollback: return -ENOMEM; } +int strv_extend_strv_consume(char ***a, char **b, bool filter_duplicates) { + _cleanup_strv_free_ char **b_consume = b; + size_t p, q, i; + + assert(a); + + q = strv_length(b); + if (q == 0) + return 0; + + p = strv_length(*a); + if (p == 0) { + strv_free_and_replace(*a, b_consume); + + if (filter_duplicates) + strv_uniq(*a); + + return strv_length(*a); + } + + if (p >= SIZE_MAX - q) + return -ENOMEM; + + char **t = reallocarray(*a, GREEDY_ALLOC_ROUND_UP(p + q + 1), sizeof(char *)); + if (!t) + return -ENOMEM; + + t[p] = NULL; + *a = t; + + if (!filter_duplicates) { + *mempcpy_typesafe(t + p, b, q) = NULL; + i = q; + } else { + i = 0; + + STRV_FOREACH(s, b) { + if (strv_contains(t, *s)) { + free(*s); + continue; + } + + t[p+i] = *s; + + i++; + t[p+i] = NULL; + } + } + + assert(i <= q); + + b_consume = mfree(b_consume); + + return (int) i; +} + #if 0 /* NM_IGNORED */ -int strv_extend_strv_concat(char ***a, char * const *b, const char *suffix) { +int strv_extend_strv_biconcat(char ***a, const char *prefix, const char* const *b, const char *suffix) { int r; + assert(a); + STRV_FOREACH(s, b) { char *v; - v = strjoin(*s, suffix); + v = strjoin(strempty(prefix), *s, suffix); if (!v) return -ENOMEM; - r = strv_push(a, v); - if (r < 0) { - free(v); + r = strv_consume(a, v); + if (r < 0) return r; - } } return 0; @@ -327,7 +445,7 @@ int strv_split_full(char ***t, const char *s, const char *separators, ExtractFla #if 0 /* NM_IGNORED */ int strv_split_and_extend_full(char ***t, const char *s, const char *separators, bool filter_duplicates, ExtractFlags flags) { - _cleanup_strv_free_ char **l = NULL; + char **l; int r; assert(t); @@ -337,7 +455,7 @@ int strv_split_and_extend_full(char ***t, const char *s, const char *separators, if (r < 0) return r; - r = strv_extend_strv(t, l, filter_duplicates); + r = strv_extend_strv_consume(t, l, filter_duplicates); if (r < 0) return r; @@ -712,7 +830,21 @@ char** strv_sort(char **l) { typesafe_qsort(l, strv_length(l), str_compare); return l; } -#endif /* NM_IGNORED */ + +char** strv_sort_uniq(char **l) { + if (strv_isempty(l)) + return l; + + char **tail = strv_sort(l), *prev = NULL; + STRV_FOREACH(i, l) + if (streq_ptr(*i, prev)) + free(*i); + else + *(tail++) = prev = *i; + + *tail = NULL; + return l; +} int strv_compare(char * const *a, char * const *b) { int r; @@ -736,6 +868,26 @@ int strv_compare(char * const *a, char * const *b) { return 0; } +bool strv_equal_ignore_order(char **a, char **b) { + + /* Just like strv_equal(), but doesn't care about the order of elements or about redundant entries + * (i.e. it's even ok if the number of entries in the array differ, as long as the difference just + * consists of repititions) */ + + if (a == b) + return true; + + STRV_FOREACH(i, a) + if (!strv_contains(b, *i)) + return false; + + STRV_FOREACH(i, b) + if (!strv_contains(a, *i)) + return false; + + return true; +} + void strv_print_full(char * const *l, const char *prefix) { STRV_FOREACH(s, l) printf("%s%s\n", strempty(prefix), *s); @@ -755,6 +907,7 @@ int strv_extendf(char ***l, const char *format, ...) { return strv_consume(l, x); } +#endif /* NM_IGNORED */ char* startswith_strv(const char *s, char * const *l) { STRV_FOREACH(i, l) { @@ -920,10 +1073,17 @@ int fputstrv(FILE *f, char * const *l, const char *separator, bool *space) { return 0; } +#if 0 /* NM_IGNORED */ +DEFINE_PRIVATE_HASH_OPS_FULL(string_strv_hash_ops, char, string_hash_func, string_compare_func, free, char*, strv_free); + static int string_strv_hashmap_put_internal(Hashmap *h, const char *key, const char *value) { char **l; int r; + assert(h); + assert(key); + assert(value); + l = hashmap_get(h, key); if (l) { /* A list for this key already exists, let's append to it if it is not listed yet */ @@ -951,6 +1111,7 @@ static int string_strv_hashmap_put_internal(Hashmap *h, const char *key, const c r = hashmap_put(h, t, l2); if (r < 0) return r; + TAKE_PTR(t); TAKE_PTR(l2); } @@ -961,6 +1122,10 @@ static int string_strv_hashmap_put_internal(Hashmap *h, const char *key, const c int _string_strv_hashmap_put(Hashmap **h, const char *key, const char *value HASHMAP_DEBUG_PARAMS) { int r; + assert(h); + assert(key); + assert(value); + r = _hashmap_ensure_allocated(h, &string_strv_hash_ops HASHMAP_DEBUG_PASS_ARGS); if (r < 0) return r; @@ -971,6 +1136,10 @@ int _string_strv_hashmap_put(Hashmap **h, const char *key, const char *value HA int _string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value HASHMAP_DEBUG_PARAMS) { int r; + assert(h); + assert(key); + assert(value); + r = _ordered_hashmap_ensure_allocated(h, &string_strv_hash_ops HASHMAP_DEBUG_PASS_ARGS); if (r < 0) return r; @@ -978,4 +1147,91 @@ int _string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const return string_strv_hashmap_put_internal(PLAIN_HASHMAP(*h), key, value); } -DEFINE_HASH_OPS_FULL(string_strv_hash_ops, char, string_hash_func, string_compare_func, free, char*, strv_free); +int strv_rebreak_lines(char **l, size_t width, char ***ret) { + _cleanup_strv_free_ char **broken = NULL; + int r; + + assert(ret); + + /* Implements a simple UTF-8 line breaking algorithm + * + * Goes through all entries in *l, and line-breaks each line that is longer than the specified + * character width. Breaks at the end of words/beginning of whitespace. Lines that do not contain whitespace are not + * broken. Retains whitespace at beginning of lines, removes it at end of lines. */ + + if (width == SIZE_MAX) { /* NOP? */ + broken = strv_copy(l); + if (!broken) + return -ENOMEM; + + *ret = TAKE_PTR(broken); + return 0; + } + + STRV_FOREACH(i, l) { + const char *start = *i, *whitespace_begin = NULL, *whitespace_end = NULL; + bool in_prefix = true; /* still in the whitespace in the beginning of the line? */ + size_t w = 0; + + for (const char *p = start; *p != 0; p = utf8_next_char(p)) { + if (strchr(NEWLINE, *p)) { + in_prefix = true; + whitespace_begin = whitespace_end = NULL; + w = 0; + } else if (strchr(WHITESPACE, *p)) { + if (!in_prefix && (!whitespace_begin || whitespace_end)) { + whitespace_begin = p; + whitespace_end = NULL; + } + } else { + if (whitespace_begin && !whitespace_end) + whitespace_end = p; + + in_prefix = false; + } + + int cw = utf8_char_console_width(p); + if (cw < 0) { + log_debug_errno(cw, "Comment to line break contains invalid UTF-8, ignoring."); + cw = 1; + } + + w += cw; + + if (w > width && whitespace_begin && whitespace_end) { + _cleanup_free_ char *truncated = NULL; + + truncated = strndup(start, whitespace_begin - start); + if (!truncated) + return -ENOMEM; + + r = strv_consume(&broken, TAKE_PTR(truncated)); + if (r < 0) + return r; + + p = start = whitespace_end; + whitespace_begin = whitespace_end = NULL; + w = cw; + } + } + + /* Process rest of the line */ + assert(start); + if (in_prefix) /* Never seen anything non-whitespace? Generate empty line! */ + r = strv_extend(&broken, ""); + else if (whitespace_begin && !whitespace_end) { /* Ends in whitespace? Chop it off! */ + _cleanup_free_ char *truncated = strndup(start, whitespace_begin - start); + if (!truncated) + return -ENOMEM; + + r = strv_consume(&broken, TAKE_PTR(truncated)); + } else /* Otherwise use line as is */ + r = strv_extend(&broken, start); + if (r < 0) + return r; + } + + *ret = TAKE_PTR(broken); + return 0; +} +#endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/strv.h b/src/libnm-systemd-shared/src/basic/strv.h index 91337b92..86ba06f8 100644 --- a/src/libnm-systemd-shared/src/basic/strv.h +++ b/src/libnm-systemd-shared/src/basic/strv.h @@ -17,6 +17,7 @@ char* strv_find(char * const *l, const char *name) _pure_; char* strv_find_case(char * const *l, const char *name) _pure_; char* strv_find_prefix(char * const *l, const char *name) _pure_; char* strv_find_startswith(char * const *l, const char *name) _pure_; +char* strv_find_closest(char * const *l, const char *name) _pure_; /* Given two vectors, the first a list of keys and the second a list of key-value pairs, returns the value * of the first key from the first vector that is found in the second vector. */ char* strv_find_first_field(char * const *needles, char * const *haystack) _pure_; @@ -43,7 +44,13 @@ int strv_copy_unless_empty(char * const *l, char ***ret); size_t strv_length(char * const *l) _pure_; int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates); -int strv_extend_strv_concat(char ***a, char * const *b, const char *suffix); +int strv_extend_strv_consume(char ***a, char **b, bool filter_duplicates); + +int strv_extend_strv_biconcat(char ***a, const char *prefix, const char* const *b, const char *suffix); +static inline int strv_extend_strv_concat(char ***a, const char* const *b, const char *suffix) { + return strv_extend_strv_biconcat(a, NULL, b, suffix); +} + int strv_prepend(char ***l, const char *value); /* _with_size() are lower-level functions where the size can be provided externally, @@ -89,6 +96,8 @@ static inline bool strv_equal(char * const *a, char * const *b) { return strv_compare(a, b) == 0; } +bool strv_equal_ignore_order(char **a, char **b); + char** strv_new_internal(const char *x, ...) _sentinel_; char** strv_new_ap(const char *x, va_list ap); #define strv_new(...) strv_new_internal(__VA_ARGS__, NULL) @@ -150,7 +159,7 @@ bool strv_overlap(char * const *a, char * const *b) _pure_; _STRV_FOREACH_BACKWARDS(s, l, UNIQ_T(h, UNIQ), UNIQ_T(i, UNIQ)) #define _STRV_FOREACH_PAIR(x, y, l, i) \ - for (typeof(*l) *x, *y, *i = (l); \ + for (typeof(*(l)) *x, *y, *i = (l); \ i && *(x = i) && *(y = i + 1); \ i += 2) @@ -158,6 +167,7 @@ bool strv_overlap(char * const *a, char * const *b) _pure_; _STRV_FOREACH_PAIR(x, y, l, UNIQ_T(i, UNIQ)) char** strv_sort(char **l); +char** strv_sort_uniq(char **l); void strv_print_full(char * const *l, const char *prefix); static inline void strv_print(char * const *l) { strv_print_full(l, NULL); @@ -231,7 +241,6 @@ bool strv_fnmatch_full(char* const* patterns, const char *s, int flags, size_t * static inline bool strv_fnmatch(char* const* patterns, const char *s) { return strv_fnmatch_full(patterns, s, 0, NULL); } - static inline bool strv_fnmatch_or_empty(char* const* patterns, const char *s, int flags) { assert(s); return strv_isempty(patterns) || @@ -249,8 +258,9 @@ int fputstrv(FILE *f, char * const *l, const char *separator, bool *space); #define strv_free_and_replace(a, b) \ free_and_replace_full(a, b, strv_free) -extern const struct hash_ops string_strv_hash_ops; int _string_strv_hashmap_put(Hashmap **h, const char *key, const char *value HASHMAP_DEBUG_PARAMS); int _string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value HASHMAP_DEBUG_PARAMS); #define string_strv_hashmap_put(h, k, v) _string_strv_hashmap_put(h, k, v HASHMAP_DEBUG_SRC_ARGS) #define string_strv_ordered_hashmap_put(h, k, v) _string_strv_ordered_hashmap_put(h, k, v HASHMAP_DEBUG_SRC_ARGS) + +int strv_rebreak_lines(char **l, size_t width, char ***ret); diff --git a/src/libnm-systemd-shared/src/basic/time-util.c b/src/libnm-systemd-shared/src/basic/time-util.c index 47f5bb5a..594d5315 100644 --- a/src/libnm-systemd-shared/src/basic/time-util.c +++ b/src/libnm-systemd-shared/src/basic/time-util.c @@ -85,7 +85,7 @@ triple_timestamp* triple_timestamp_now(triple_timestamp *ts) { return ts; } -static usec_t map_clock_usec_internal(usec_t from, usec_t from_base, usec_t to_base) { +usec_t map_clock_usec_raw(usec_t from, usec_t from_base, usec_t to_base) { /* Maps the time 'from' between two clocks, based on a common reference point where the first clock * is at 'from_base' and the second clock at 'to_base'. Basically calculates: @@ -123,7 +123,7 @@ usec_t map_clock_usec(usec_t from, clockid_t from_clock, clockid_t to_clock) { if (from == USEC_INFINITY) return from; - return map_clock_usec_internal(from, now(from_clock), now(to_clock)); + return map_clock_usec_raw(from, now(from_clock), now(to_clock)); } dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) { @@ -152,8 +152,8 @@ triple_timestamp* triple_timestamp_from_realtime(triple_timestamp *ts, usec_t u) nowr = now(CLOCK_REALTIME); ts->realtime = u; - ts->monotonic = map_clock_usec_internal(u, nowr, now(CLOCK_MONOTONIC)); - ts->boottime = map_clock_usec_internal(u, nowr, now(CLOCK_BOOTTIME)); + ts->monotonic = map_clock_usec_raw(u, nowr, now(CLOCK_MONOTONIC)); + ts->boottime = map_clock_usec_raw(u, nowr, now(CLOCK_BOOTTIME)); return ts; } @@ -171,8 +171,8 @@ triple_timestamp* triple_timestamp_from_boottime(triple_timestamp *ts, usec_t u) nowb = now(CLOCK_BOOTTIME); ts->boottime = u; - ts->monotonic = map_clock_usec_internal(u, nowb, now(CLOCK_MONOTONIC)); - ts->realtime = map_clock_usec_internal(u, nowb, now(CLOCK_REALTIME)); + ts->monotonic = map_clock_usec_raw(u, nowb, now(CLOCK_MONOTONIC)); + ts->realtime = map_clock_usec_raw(u, nowb, now(CLOCK_REALTIME)); return ts; } @@ -201,8 +201,8 @@ dual_timestamp* dual_timestamp_from_boottime(dual_timestamp *ts, usec_t u) { } nowm = now(CLOCK_BOOTTIME); - ts->monotonic = map_clock_usec_internal(u, nowm, now(CLOCK_MONOTONIC)); - ts->realtime = map_clock_usec_internal(u, nowm, now(CLOCK_REALTIME)); + ts->monotonic = map_clock_usec_raw(u, nowm, now(CLOCK_MONOTONIC)); + ts->realtime = map_clock_usec_raw(u, nowm, now(CLOCK_REALTIME)); return ts; } @@ -315,7 +315,7 @@ struct timeval *timeval_store(struct timeval *tv, usec_t u) { return tv; } -char *format_timestamp_style( +char* format_timestamp_style( char *buf, size_t l, usec_t t, @@ -335,7 +335,6 @@ char *format_timestamp_style( struct tm tm; bool utc, us; - time_t sec; size_t n; assert(buf); @@ -378,9 +377,7 @@ char *format_timestamp_style( return strcpy(buf, xxx[style]); } - sec = (time_t) (t / USEC_PER_SEC); /* Round down */ - - if (!localtime_or_gmtime_r(&sec, &tm, utc)) + if (localtime_or_gmtime_usec(t, utc, &tm) < 0) return NULL; /* Start with the week day */ @@ -563,7 +560,7 @@ char* format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) { /* The result of this function can be parsed with parse_sec */ - for (size_t i = 0; i < ELEMENTSOF(table); i++) { + FOREACH_ELEMENT(i, table) { int k = 0; size_t n; bool done = false; @@ -575,20 +572,20 @@ char* format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) { if (t < accuracy && something) break; - if (t < table[i].usec) + if (t < i->usec) continue; if (l <= 1) break; - a = t / table[i].usec; - b = t % table[i].usec; + a = t / i->usec; + b = t % i->usec; /* Let's see if we should shows this in dot notation */ if (t < USEC_PER_MINUTE && b > 0) { signed char j = 0; - for (usec_t cc = table[i].usec; cc > 1; cc /= 10) + for (usec_t cc = i->usec; cc > 1; cc /= 10) j++; for (usec_t cc = accuracy; cc > 1; cc /= 10) { @@ -603,7 +600,7 @@ char* format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) { a, j, b, - table[i].suffix); + i->suffix); t = 0; done = true; @@ -616,7 +613,7 @@ char* format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) { "%s"USEC_FMT"%s", p > buf ? " " : "", a, - table[i].suffix); + i->suffix); t = b; } @@ -670,7 +667,6 @@ static int parse_timestamp_impl( unsigned fractional = 0; const char *k; struct tm tm, copy; - time_t sec; /* Allowed syntaxes: * @@ -783,10 +779,9 @@ static int parse_timestamp_impl( } } - sec = (time_t) (usec / USEC_PER_SEC); - - if (!localtime_or_gmtime_r(&sec, &tm, utc)) - return -EINVAL; + r = localtime_or_gmtime_usec(usec, utc, &tm); + if (r < 0) + return r; tm.tm_isdst = isdst; @@ -805,12 +800,12 @@ static int parse_timestamp_impl( goto from_tm; } - for (size_t i = 0; i < ELEMENTSOF(day_nr); i++) { - k = startswith_no_case(t, day_nr[i].name); + FOREACH_ELEMENT(day, day_nr) { + k = startswith_no_case(t, day->name); if (!k || *k != ' ') continue; - weekday = day_nr[i].nr; + weekday = day->nr; t = k + 1; break; } @@ -944,11 +939,11 @@ from_tm: } else minus = gmtoff * USEC_PER_SEC; - sec = mktime_or_timegm(&tm, utc); - if (sec < 0) - return -EINVAL; + r = mktime_or_timegm_usec(&tm, utc, &usec); + if (r < 0) + return r; - usec = usec_add(sec * USEC_PER_SEC, fractional); + usec = usec_add(usec, fractional); finish: usec = usec_add(usec, plus); @@ -1004,8 +999,12 @@ int parse_timestamp(const char *t, usec_t *ret) { assert(t); t_len = strlen(t); - if (t_len > 2 && t[t_len - 1] == 'Z' && t[t_len - 2] != ' ') /* RFC3339-style welded UTC: "1985-04-12T23:20:50.52Z" */ - return parse_timestamp_impl(t, t_len - 1, /* utc = */ true, /* isdst = */ -1, /* gmtoff = */ 0, ret); + if (t_len > 2 && t[t_len - 1] == 'Z') { + /* Try to parse as RFC3339-style welded UTC: "1985-04-12T23:20:50.52Z" */ + r = parse_timestamp_impl(t, t_len - 1, /* utc = */ true, /* isdst = */ -1, /* gmtoff = */ 0, ret); + if (r >= 0) + return r; + } if (t_len > 7 && IN_SET(t[t_len - 6], '+', '-') && t[t_len - 7] != ' ') { /* RFC3339-style welded offset: "1990-12-31T15:59:60-08:00" */ k = strptime(&t[t_len - 6], "%z", &tm); @@ -1049,6 +1048,14 @@ int parse_timestamp(const char *t, usec_t *ret) { if (shared == MAP_FAILED) return negative_errno(); + /* The input string may be in argv. Let's copy it. */ + _cleanup_free_ char *t_copy = strdup(t); + if (!t_copy) + return -ENOMEM; + + t = t_copy; + assert_se(tz = endswith(t_copy, tz)); + r = safe_fork("(sd-timestamp)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_WAIT, NULL); if (r < 0) { (void) munmap(shared, sizeof *shared); @@ -1120,12 +1127,12 @@ static const char* extract_multiplier(const char *p, usec_t *ret) { assert(p); assert(ret); - for (size_t i = 0; i < ELEMENTSOF(table); i++) { + FOREACH_ELEMENT(i, table) { char *e; - e = startswith(p, table[i].suffix); + e = startswith(p, i->suffix); if (e) { - *ret = table[i].usec; + *ret = i->usec; return e; } } @@ -1135,19 +1142,14 @@ static const char* extract_multiplier(const char *p, usec_t *ret) { int parse_time(const char *t, usec_t *ret, usec_t default_unit) { const char *p, *s; - usec_t usec = 0; - bool something = false; assert(t); assert(default_unit > 0); - p = t; - - p += strspn(p, WHITESPACE); + p = skip_leading_chars(t, /* bad = */ NULL); s = startswith(p, "infinity"); if (s) { - s += strspn(s, WHITESPACE); - if (*s != 0) + if (!in_charset(s, WHITESPACE)) return -EINVAL; if (ret) @@ -1155,13 +1157,14 @@ int parse_time(const char *t, usec_t *ret, usec_t default_unit) { return 0; } - for (;;) { + usec_t usec = 0; + + for (bool something = false;;) { usec_t multiplier = default_unit, k; long long l; char *e; - p += strspn(p, WHITESPACE); - + p = skip_leading_chars(p, /* bad = */ NULL); if (*p == 0) { if (!something) return -EINVAL; @@ -1298,17 +1301,16 @@ static const char* extract_nsec_multiplier(const char *p, nsec_t *ret) { { "ns", 1ULL }, { "", 1ULL }, /* default is nsec */ }; - size_t i; assert(p); assert(ret); - for (i = 0; i < ELEMENTSOF(table); i++) { + FOREACH_ELEMENT(i, table) { char *e; - e = startswith(p, table[i].suffix); + e = startswith(p, i->suffix); if (e) { - *ret = table[i].nsec; + *ret = i->nsec; return e; } } @@ -1524,8 +1526,7 @@ int get_timezones(char ***ret) { if (r < 0) return r; - strv_sort(zones); - strv_uniq(zones); + strv_sort_uniq(zones); *ret = TAKE_PTR(zones); return 0; @@ -1613,51 +1614,74 @@ bool clock_supported(clockid_t clock) { #if 0 /* NM_IGNORED */ int get_timezone(char **ret) { _cleanup_free_ char *t = NULL; - const char *e; - char *z; int r; assert(ret); r = readlink_malloc("/etc/localtime", &t); - if (r == -ENOENT) { + if (r == -ENOENT) /* If the symlink does not exist, assume "UTC", like glibc does */ - z = strdup("UTC"); - if (!z) - return -ENOMEM; - - *ret = z; - return 0; - } + return strdup_to(ret, "UTC"); if (r < 0) - return r; /* returns EINVAL if not a symlink */ + return r; /* Return EINVAL if not a symlink */ - e = PATH_STARTSWITH_SET(t, "/usr/share/zoneinfo/", "../usr/share/zoneinfo/"); + const char *e = PATH_STARTSWITH_SET(t, "/usr/share/zoneinfo/", "../usr/share/zoneinfo/"); if (!e) return -EINVAL; - if (!timezone_is_valid(e, LOG_DEBUG)) return -EINVAL; - z = strdup(e); - if (!z) - return -ENOMEM; - - *ret = z; - return 0; + return strdup_to(ret, e); } -time_t mktime_or_timegm(struct tm *tm, bool utc) { +int mktime_or_timegm_usec( + struct tm *tm, /* input + normalized output */ + bool utc, + usec_t *ret) { + + time_t t; + assert(tm); - return utc ? timegm(tm) : mktime(tm); + if (tm->tm_year < 69) /* early check for negative (i.e. before 1970) time_t (Note that in some timezones the epoch is in the year 1969!)*/ + return -ERANGE; + if ((usec_t) tm->tm_year > CONST_MIN(USEC_INFINITY / USEC_PER_YEAR, (usec_t) TIME_T_MAX / (365U * 24U * 60U * 60U)) - 1900) /* early check for possible overrun of usec_t or time_t */ + return -ERANGE; + + /* timegm()/mktime() is a bit weird to use, since it returns -1 in two cases: on error as well as a + * valid time indicating one second before the UNIX epoch. Let's treat both cases the same here, and + * return -ERANGE for anything negative, since usec_t is unsigned, and we can thus not express + * negative times anyway. */ + + t = utc ? timegm(tm) : mktime(tm); + if (t < 0) /* Refuse negative times and errors */ + return -ERANGE; + if ((usec_t) t >= USEC_INFINITY / USEC_PER_SEC) /* Never return USEC_INFINITY by accident (or overflow) */ + return -ERANGE; + + if (ret) + *ret = (usec_t) t * USEC_PER_SEC; + return 0; } -struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc) { - assert(t); - assert(tm); +int localtime_or_gmtime_usec( + usec_t t, + bool utc, + struct tm *ret) { - return utc ? gmtime_r(t, tm) : localtime_r(t, tm); + t /= USEC_PER_SEC; /* Round down */ + if (t > (usec_t) TIME_T_MAX) + return -ERANGE; + time_t sec = (time_t) t; + + struct tm buf = {}; + if (!(utc ? gmtime_r(&sec, &buf) : localtime_r(&sec, &buf))) + return -EINVAL; + + if (ret) + *ret = buf; + + return 0; } static uint32_t sysconf_clock_ticks_cached(void) { diff --git a/src/libnm-systemd-shared/src/basic/time-util.h b/src/libnm-systemd-shared/src/basic/time-util.h index 29373477..14d660ee 100644 --- a/src/libnm-systemd-shared/src/basic/time-util.h +++ b/src/libnm-systemd-shared/src/basic/time-util.h @@ -71,12 +71,16 @@ typedef enum TimestampStyle { #define TIME_T_MAX (time_t)((UINTMAX_C(1) << ((sizeof(time_t) << 3) - 1)) - 1) -#define DUAL_TIMESTAMP_NULL ((struct dual_timestamp) {}) -#define TRIPLE_TIMESTAMP_NULL ((struct triple_timestamp) {}) +#define DUAL_TIMESTAMP_NULL ((dual_timestamp) {}) +#define DUAL_TIMESTAMP_INFINITY ((dual_timestamp) { USEC_INFINITY, USEC_INFINITY }) +#define TRIPLE_TIMESTAMP_NULL ((triple_timestamp) {}) + +#define TIMESPEC_OMIT ((const struct timespec) { .tv_nsec = UTIME_OMIT }) usec_t now(clockid_t clock); nsec_t now_nsec(clockid_t clock); +usec_t map_clock_usec_raw(usec_t from, usec_t from_base, usec_t to_base); usec_t map_clock_usec(usec_t from, clockid_t from_clock, clockid_t to_clock); dual_timestamp* dual_timestamp_now(dual_timestamp *ts); @@ -173,8 +177,8 @@ usec_t usec_shift_clock(usec_t, clockid_t from, clockid_t to); int get_timezone(char **ret); -time_t mktime_or_timegm(struct tm *tm, bool utc); -struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc); +int mktime_or_timegm_usec(struct tm *tm, bool utc, usec_t *ret); +int localtime_or_gmtime_usec(usec_t t, bool utc, struct tm *ret); uint32_t usec_to_jiffies(usec_t usec); usec_t jiffies_to_usec(uint32_t jiffies); @@ -184,11 +188,7 @@ bool in_utc_timezone(void); static inline usec_t usec_add(usec_t a, usec_t b) { /* Adds two time values, and makes sure USEC_INFINITY as input results as USEC_INFINITY in output, * and doesn't overflow. */ - - if (a > USEC_INFINITY - b) /* overflow check */ - return USEC_INFINITY; - - return a + b; + return saturate_add(a, b, USEC_INFINITY); } static inline usec_t usec_sub_unsigned(usec_t timestamp, usec_t delta) { diff --git a/src/libnm-systemd-shared/src/basic/tmpfile-util.c b/src/libnm-systemd-shared/src/basic/tmpfile-util.c index a66ee82d..3d1b8d04 100644 --- a/src/libnm-systemd-shared/src/basic/tmpfile-util.c +++ b/src/libnm-systemd-shared/src/basic/tmpfile-util.c @@ -122,6 +122,17 @@ int fmkostemp_safe(char *pattern, const char *mode, FILE **ret_f) { } #endif /* NM_IGNORED */ +void unlink_tempfilep(char (*p)[]) { + assert(p); + + /* If the file is created with mkstemp(), it will (almost always) change the suffix. + * Treat this as a sign that the file was successfully created. We ignore both the rare case + * where the original suffix is used and unlink failures. */ + + if (!endswith(*p, ".XXXXXX")) + (void) unlink(*p); +} + static int tempfn_build(const char *p, const char *pre, const char *post, bool child, char **ret) { _cleanup_free_ char *d = NULL, *fn = NULL, *nf = NULL, *result = NULL; size_t len_pre, len_post, len_add; @@ -335,28 +346,7 @@ int fopen_tmpfile_linkable(const char *target, int flags, char **ret_path, FILE return 0; } -static int link_fd(int fd, int newdirfd, const char *newpath) { - int r; - - assert(fd >= 0); - assert(newdirfd >= 0 || newdirfd == AT_FDCWD); - assert(newpath); - - /* Try symlinking via /proc/fd/ first. */ - r = RET_NERRNO(linkat(AT_FDCWD, FORMAT_PROC_FD_PATH(fd), newdirfd, newpath, AT_SYMLINK_FOLLOW)); - if (r != -ENOENT) - return r; - - /* Fall back to symlinking via AT_EMPTY_PATH as fallback (this requires CAP_DAC_READ_SEARCH and a - * more recent kernel, but does not require /proc/ mounted) */ - if (proc_mounted() != 0) - return r; - - return RET_NERRNO(linkat(fd, "", newdirfd, newpath, AT_EMPTY_PATH)); -} - int link_tmpfile_at(int fd, int dir_fd, const char *path, const char *target, LinkTmpfileFlags flags) { - _cleanup_free_ char *tmp = NULL; int r; assert(fd >= 0); @@ -375,33 +365,14 @@ int link_tmpfile_at(int fd, int dir_fd, const char *path, const char *target, Li r = RET_NERRNO(renameat(dir_fd, path, dir_fd, target)); else r = rename_noreplace(dir_fd, path, dir_fd, target); - if (r < 0) - return r; } else { - - r = link_fd(fd, dir_fd, target); - if (r != -EEXIST || !FLAGS_SET(flags, LINK_TMPFILE_REPLACE)) - return r; - - /* So the target already exists and we were asked to replace it. That sucks a bit, since the kernel's - * linkat() logic does not allow that. We work-around this by linking the file to a random name - * first, and then renaming that to the final name. This reintroduces the race O_TMPFILE kinda is - * trying to fix, but at least the vulnerability window (i.e. where the file is linked into the file - * system under a temporary name) is very short. */ - - r = tempfn_random(target, NULL, &tmp); - if (r < 0) - return r; - - if (link_fd(fd, dir_fd, tmp) < 0) - return -EEXIST; /* propagate original error */ - - r = RET_NERRNO(renameat(dir_fd, tmp, dir_fd, target)); - if (r < 0) { - (void) unlinkat(dir_fd, tmp, 0); - return r; - } + if (FLAGS_SET(flags, LINK_TMPFILE_REPLACE)) + r = linkat_replace(fd, /* oldpath= */ NULL, dir_fd, target); + else + r = link_fd(fd, dir_fd, target); } + if (r < 0) + return r; if (FLAGS_SET(flags, LINK_TMPFILE_SYNC)) { r = fsync_full(fd); diff --git a/src/libnm-systemd-shared/src/basic/tmpfile-util.h b/src/libnm-systemd-shared/src/basic/tmpfile-util.h index 8c917c06..408f80e1 100644 --- a/src/libnm-systemd-shared/src/basic/tmpfile-util.h +++ b/src/libnm-systemd-shared/src/basic/tmpfile-util.h @@ -18,6 +18,8 @@ static inline int fopen_temporary_child(const char *path, FILE **ret_file, char int mkostemp_safe(char *pattern); int fmkostemp_safe(char *pattern, const char *mode, FILE**_f); +void unlink_tempfilep(char (*p)[]); + int tempfn_xxxxxx(const char *p, const char *extra, char **ret); int tempfn_random(const char *p, const char *extra, char **ret); int tempfn_random_child(const char *p, const char *extra, char **ret); diff --git a/src/libnm-systemd-shared/src/basic/user-util.h b/src/libnm-systemd-shared/src/basic/user-util.h index 9d07ef31..653f1425 100644 --- a/src/libnm-systemd-shared/src/basic/user-util.h +++ b/src/libnm-systemd-shared/src/basic/user-util.h @@ -12,6 +12,8 @@ #include <sys/types.h> #include <unistd.h> +#include "string-util.h" + /* Users managed by systemd-homed. See https://systemd.io/UIDS-GIDS for details how this range fits into the rest of the world */ #define HOME_UID_MIN ((uid_t) 60001) #define HOME_UID_MAX ((uid_t) 60513) @@ -36,10 +38,20 @@ static inline int parse_gid(const char *s, gid_t *ret_gid) { char* getlogname_malloc(void); char* getusername_malloc(void); +const char* default_root_shell_at(int rfd); +const char* default_root_shell(const char *root); + +bool is_nologin_shell(const char *shell); + +static inline bool shell_is_placeholder(const char *shell) { + return isempty(shell) || is_nologin_shell(shell); +} + typedef enum UserCredsFlags { - USER_CREDS_PREFER_NSS = 1 << 0, /* if set, only synthesize user records if database lacks them. Normally we bypass the userdb entirely for the records we can synthesize */ - USER_CREDS_ALLOW_MISSING = 1 << 1, /* if a numeric UID string is resolved, be OK if there's no record for it */ - USER_CREDS_CLEAN = 1 << 2, /* try to clean up shell and home fields with invalid data */ + USER_CREDS_PREFER_NSS = 1 << 0, /* if set, only synthesize user records if database lacks them. Normally we bypass the userdb entirely for the records we can synthesize */ + USER_CREDS_ALLOW_MISSING = 1 << 1, /* if a numeric UID string is resolved, be OK if there's no record for it */ + USER_CREDS_CLEAN = 1 << 2, /* try to clean up shell and home fields with invalid data */ + USER_CREDS_SUPPRESS_PLACEHOLDER = 1 << 3, /* suppress home and/or shell fields if value is placeholder (root/empty/nologin) */ } UserCredsFlags; int get_user_creds(const char **username, uid_t *ret_uid, gid_t *ret_gid, const char **ret_home, const char **ret_shell, UserCredsFlags flags); @@ -52,7 +64,7 @@ int in_gid(gid_t gid); int in_group(const char *name); int merge_gid_lists(const gid_t *list1, size_t size1, const gid_t *list2, size_t size2, gid_t **result); -int getgroups_alloc(gid_t** gids); +int getgroups_alloc(gid_t **ret); int get_home_dir(char **ret); int get_shell(char **ret); @@ -108,15 +120,7 @@ bool valid_user_group_name(const char *u, ValidUserFlags flags); bool valid_gecos(const char *d); char* mangle_gecos(const char *d); bool valid_home(const char *p); - -static inline bool valid_shell(const char *p) { - /* We have the same requirements, so just piggy-back on the home check. - * - * Let's ignore /etc/shells because this is only applicable to real and - * not system users. It is also incompatible with the idea of empty /etc. - */ - return valid_home(p); -} +bool valid_shell(const char *p); int maybe_setgroups(size_t size, const gid_t *list); @@ -133,10 +137,6 @@ int fgetsgent_sane(FILE *stream, struct sgrp **sg); int putsgent_sane(const struct sgrp *sg, FILE *stream); #endif -bool is_nologin_shell(const char *shell); -const char* default_root_shell_at(int rfd); -const char* default_root_shell(const char *root); - int is_this_me(const char *username); const char* get_home_root(void); diff --git a/src/libnm-systemd-shared/src/basic/utf8.c b/src/libnm-systemd-shared/src/basic/utf8.c index cf24e82f..33fdd96e 100644 --- a/src/libnm-systemd-shared/src/basic/utf8.c +++ b/src/libnm-systemd-shared/src/basic/utf8.c @@ -1,26 +1,10 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* SPDX-License-Identifier: LGPL-2.0-or-later */ -/* Parts of this file are based on the GLIB utf8 validation functions. The - * original license text follows. */ - -/* gutf8.c - Operations on UTF-8 strings. +/* Parts of this file are based on the GLIB utf8 validation functions. The original copyright follows. * + * gutf8.c - Operations on UTF-8 strings. * Copyright (C) 1999 Tom Tromey * Copyright (C) 2000 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "nm-sd-adapt-shared.h" @@ -148,30 +132,30 @@ bool utf8_is_printable_newline(const char* str, size_t length, bool allow_newlin return true; } -char *utf8_is_valid_n(const char *str, size_t len_bytes) { +char* utf8_is_valid_n(const char *str, size_t len_bytes) { /* Check if the string is composed of valid utf8 characters. If length len_bytes is given, stop after * len_bytes. Otherwise, stop at NUL. */ assert(str); - for (const char *p = str; len_bytes != SIZE_MAX ? (size_t) (p - str) < len_bytes : *p != '\0'; ) { + for (size_t i = 0; len_bytes != SIZE_MAX ? i < len_bytes : str[i] != '\0'; ) { int len; - if (_unlikely_(*p == '\0') && len_bytes != SIZE_MAX) + if (_unlikely_(str[i] == '\0')) return NULL; /* embedded NUL */ - len = utf8_encoded_valid_unichar(p, - len_bytes != SIZE_MAX ? len_bytes - (p - str) : SIZE_MAX); + len = utf8_encoded_valid_unichar(str + i, + len_bytes != SIZE_MAX ? len_bytes - i : SIZE_MAX); if (_unlikely_(len < 0)) return NULL; /* invalid character */ - p += len; + i += len; } return (char*) str; } -char *utf8_escape_invalid(const char *str) { +char* utf8_escape_invalid(const char *str) { char *p, *s; assert(str); @@ -198,7 +182,7 @@ char *utf8_escape_invalid(const char *str) { } #if 0 /* NM_IGNORED */ -static int utf8_char_console_width(const char *str) { +int utf8_char_console_width(const char *str) { char32_t c; int r; @@ -206,12 +190,15 @@ static int utf8_char_console_width(const char *str) { if (r < 0) return r; + if (c == '\t') + return 8; /* Assume a tab width of 8 */ + /* TODO: we should detect combining characters */ return unichar_iswide(c) ? 2 : 1; } -char *utf8_escape_non_printable_full(const char *str, size_t console_width, bool force_ellipsis) { +char* utf8_escape_non_printable_full(const char *str, size_t console_width, bool force_ellipsis) { char *p, *s, *prev_s; size_t n = 0; /* estimated print width */ @@ -288,33 +275,18 @@ char *utf8_escape_non_printable_full(const char *str, size_t console_width, bool } #endif /* NM_IGNORED */ -char *ascii_is_valid(const char *str) { - /* Check whether the string consists of valid ASCII bytes, - * i.e values between 0 and 127, inclusive. */ - - assert(str); - - for (const char *p = str; *p; p++) - if ((unsigned char) *p >= 128) - return NULL; - - return (char*) str; -} - -#if 0 /* NM_IGNORED */ -char *ascii_is_valid_n(const char *str, size_t len) { - /* Very similar to ascii_is_valid(), but checks exactly len - * bytes and rejects any NULs in that range. */ +char* ascii_is_valid_n(const char *str, size_t len) { + /* Check whether the string consists of valid ASCII bytes, i.e values between 1 and 127, inclusive. + * Stops at len, or NUL byte if len is SIZE_MAX. */ assert(str); - for (size_t i = 0; i < len; i++) - if ((unsigned char) str[i] >= 128 || str[i] == 0) + for (size_t i = 0; len != SIZE_MAX ? i < len : str[i] != '\0'; i++) + if ((unsigned char) str[i] >= 128 || str[i] == '\0') return NULL; return (char*) str; } -#endif /* NM_IGNORED */ int utf8_to_ascii(const char *str, char replacement_char, char **ret) { /* Convert to a string that has only ASCII chars, replacing anything that is not ASCII @@ -392,7 +364,7 @@ size_t utf8_encode_unichar(char *out_utf8, char32_t g) { } #if 0 /* NM_IGNORED */ -char *utf16_to_utf8(const char16_t *s, size_t length /* bytes! */) { +char* utf16_to_utf8(const char16_t *s, size_t length /* bytes! */) { const uint8_t *f; char *r, *t; @@ -536,6 +508,10 @@ size_t char16_strlen(const char16_t *s) { return n; } + +size_t char16_strsize(const char16_t *s) { + return s ? (char16_strlen(s) + 1) * sizeof(*s) : 0; +} #endif /* NM_IGNORED */ /* expected size used to encode one unicode char */ @@ -619,11 +595,14 @@ size_t utf8_n_codepoints(const char *str) { } size_t utf8_console_width(const char *str) { - size_t n = 0; + + if (isempty(str)) + return 0; /* Returns the approximate width a string will take on screen when printed on a character cell * terminal/console. */ + size_t n = 0; while (*str) { int w; diff --git a/src/libnm-systemd-shared/src/basic/utf8.h b/src/libnm-systemd-shared/src/basic/utf8.h index 962312c5..221bc46a 100644 --- a/src/libnm-systemd-shared/src/basic/utf8.h +++ b/src/libnm-systemd-shared/src/basic/utf8.h @@ -14,31 +14,35 @@ bool unichar_is_valid(char32_t c); -char *utf8_is_valid_n(const char *str, size_t len_bytes) _pure_; -static inline char *utf8_is_valid(const char *s) { - return utf8_is_valid_n(s, SIZE_MAX); +char* utf8_is_valid_n(const char *str, size_t len_bytes) _pure_; +static inline char* utf8_is_valid(const char *str) { + return utf8_is_valid_n(str, SIZE_MAX); +} + +char* ascii_is_valid_n(const char *str, size_t len) _pure_; +static inline char* ascii_is_valid(const char *str) { + return ascii_is_valid_n(str, SIZE_MAX); } -char *ascii_is_valid(const char *s) _pure_; -char *ascii_is_valid_n(const char *str, size_t len); int utf8_to_ascii(const char *str, char replacement_char, char **ret); bool utf8_is_printable_newline(const char* str, size_t length, bool allow_newline) _pure_; #define utf8_is_printable(str, length) utf8_is_printable_newline(str, length, true) -char *utf8_escape_invalid(const char *s); -char *utf8_escape_non_printable_full(const char *str, size_t console_width, bool force_ellipsis); -static inline char *utf8_escape_non_printable(const char *str) { +char* utf8_escape_invalid(const char *s); +char* utf8_escape_non_printable_full(const char *str, size_t console_width, bool force_ellipsis); +static inline char* utf8_escape_non_printable(const char *str) { return utf8_escape_non_printable_full(str, SIZE_MAX, false); } size_t utf8_encode_unichar(char *out_utf8, char32_t g); size_t utf16_encode_unichar(char16_t *out, char32_t c); -char *utf16_to_utf8(const char16_t *s, size_t length /* bytes! */); +char* utf16_to_utf8(const char16_t *s, size_t length /* bytes! */); char16_t *utf8_to_utf16(const char *s, size_t length); size_t char16_strlen(const char16_t *s); /* returns the number of 16-bit words in the string (not bytes!) */ +size_t char16_strsize(const char16_t *s); int utf8_encoded_valid_unichar(const char *str, size_t length); int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar); @@ -56,4 +60,5 @@ static inline char32_t utf16_surrogate_pair_to_unichar(char16_t lead, char16_t t } size_t utf8_n_codepoints(const char *str); +int utf8_char_console_width(const char *str); size_t utf8_console_width(const char *str); diff --git a/src/libnm-systemd-shared/src/fundamental/iovec-util-fundamental.h b/src/libnm-systemd-shared/src/fundamental/iovec-util-fundamental.h new file mode 100644 index 00000000..68d5bf4e --- /dev/null +++ b/src/libnm-systemd-shared/src/fundamental/iovec-util-fundamental.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#if SD_BOOT +/* struct iovec is a POSIX userspace construct. Let's introduce it also in EFI mode, it's just so useful */ +struct iovec { + void *iov_base; + size_t iov_len; +}; + +static inline void free(void *p); +#endif + +/* This accepts both const and non-const pointers */ +#define IOVEC_MAKE(base, len) \ + (struct iovec) { \ + .iov_base = (void*) (base), \ + .iov_len = (len), \ + } + +static inline void iovec_done(struct iovec *iovec) { + /* A _cleanup_() helper that frees the iov_base in the iovec */ + assert(iovec); + + iovec->iov_base = mfree(iovec->iov_base); + iovec->iov_len = 0; +} + +static inline bool iovec_is_set(const struct iovec *iovec) { + /* Checks if the iovec points to a non-empty chunk of memory */ + return iovec && iovec->iov_len > 0 && iovec->iov_base; +} + +static inline bool iovec_is_valid(const struct iovec *iovec) { + /* Checks if the iovec is either NULL, empty or points to a valid bit of memory */ + return !iovec || (iovec->iov_base || iovec->iov_len == 0); +} diff --git a/src/libnm-systemd-shared/src/fundamental/macro-fundamental.h b/src/libnm-systemd-shared/src/fundamental/macro-fundamental.h index 00f2a2b9..418ea55f 100644 --- a/src/libnm-systemd-shared/src/fundamental/macro-fundamental.h +++ b/src/libnm-systemd-shared/src/fundamental/macro-fundamental.h @@ -32,6 +32,10 @@ _Pragma("GCC diagnostic push"); \ _Pragma("GCC diagnostic ignored \"-Wshadow\"") +#define DISABLE_WARNING_STRINGOP_OVERREAD \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wstringop-overread\"") + #define DISABLE_WARNING_INCOMPATIBLE_POINTER_TYPES \ _Pragma("GCC diagnostic push"); \ _Pragma("GCC diagnostic ignored \"-Wincompatible-pointer-types\"") @@ -44,6 +48,32 @@ _Pragma("GCC diagnostic push"); \ _Pragma("GCC diagnostic ignored \"-Waddress\"") +#define DISABLE_WARNING_STRINGOP_TRUNCATION \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wstringop-truncation\"") + +#if 0 /* NM_IGNORED */ + +#if HAVE_WARNING_ZERO_LENGTH_BOUNDS +# define DISABLE_WARNING_ZERO_LENGTH_BOUNDS \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wzero-length-bounds\"") +#else +# define DISABLE_WARNING_ZERO_LENGTH_BOUNDS \ + _Pragma("GCC diagnostic push") +#endif + +#if HAVE_WARNING_ZERO_AS_NULL_POINTER_CONSTANT +# define DISABLE_WARNING_ZERO_AS_NULL_POINTER_CONSTANT \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wzero-as-null-pointer-constant\"") +#else +# define DISABLE_WARNING_ZERO_AS_NULL_POINTER_CONSTANT \ + _Pragma("GCC diagnostic push") +#endif + +#endif /* NM_IGNORED */ + #define REENABLE_WARNING \ _Pragma("GCC diagnostic pop") @@ -87,10 +117,10 @@ # define _alloc_(...) __attribute__((__alloc_size__(__VA_ARGS__))) #endif -#if __GNUC__ >= 7 || (defined(__clang__) && __clang_major__ >= 10) -# define _fallthrough_ __attribute__((__fallthrough__)) -#else +#if defined(__clang__) && __clang_major__ < 10 # define _fallthrough_ +#else +# define _fallthrough_ __attribute__((__fallthrough__)) #endif #define XSTRINGIFY(x) #x @@ -288,6 +318,30 @@ MUL_SAFE(UNIQ_T(A, q), *UNIQ_T(A, q), b); \ }) +#define ADD_SAFE(ret, a, b) (!__builtin_add_overflow(a, b, ret)) +#define INC_SAFE(a, b) __INC_SAFE(UNIQ, a, b) +#define __INC_SAFE(q, a, b) \ + ({ \ + const typeof(a) UNIQ_T(A, q) = (a); \ + ADD_SAFE(UNIQ_T(A, q), *UNIQ_T(A, q), b); \ + }) + +#define SUB_SAFE(ret, a, b) (!__builtin_sub_overflow(a, b, ret)) +#define DEC_SAFE(a, b) __DEC_SAFE(UNIQ, a, b) +#define __DEC_SAFE(q, a, b) \ + ({ \ + const typeof(a) UNIQ_T(A, q) = (a); \ + SUB_SAFE(UNIQ_T(A, q), *UNIQ_T(A, q), b); \ + }) + +#define MUL_SAFE(ret, a, b) (!__builtin_mul_overflow(a, b, ret)) +#define MUL_ASSIGN_SAFE(a, b) __MUL_ASSIGN_SAFE(UNIQ, a, b) +#define __MUL_ASSIGN_SAFE(q, a, b) \ + ({ \ + const typeof(a) UNIQ_T(A, q) = (a); \ + MUL_SAFE(UNIQ_T(A, q), *UNIQ_T(A, q), b); \ + }) + #define LESS_BY(a, b) __LESS_BY(UNIQ, (a), UNIQ, (b)) #define __LESS_BY(aq, a, bq, b) \ ({ \ @@ -532,6 +586,10 @@ static inline uint64_t ALIGN_OFFSET_U64(uint64_t l, uint64_t ali) { } \ } +/* Restriction/bug (see below) was fixed in GCC 15 and clang 19. */ +#if __GNUC__ >= 15 || (defined(__clang__) && __clang_major__ >= 19) +#define DECLARE_FLEX_ARRAY(type, name) type name[] +#else /* Declare a flexible array usable in a union. * This is essentially a work-around for a pointless constraint in C99 * and might go away in some future version of the standard. @@ -543,12 +601,12 @@ static inline uint64_t ALIGN_OFFSET_U64(uint64_t l, uint64_t ali) { dummy_t __empty__ ## name; \ type name[]; \ } +#endif /* Declares an ELF read-only string section that does not occupy memory at runtime. */ #define DECLARE_NOALLOC_SECTION(name, text) \ asm(".pushsection " name ",\"S\"\n\t" \ ".ascii " STRINGIFY(text) "\n\t" \ - ".zero 1\n\t" \ ".popsection\n") #ifdef SBAT_DISTRO @@ -556,3 +614,22 @@ static inline uint64_t ALIGN_OFFSET_U64(uint64_t l, uint64_t ali) { #else #define DECLARE_SBAT(text) #endif + +#define sizeof_field(struct_type, member) sizeof(((struct_type *) 0)->member) +#define endoffsetof_field(struct_type, member) (offsetof(struct_type, member) + sizeof_field(struct_type, member)) +#define voffsetof(v, member) offsetof(typeof(v), member) + +#define _FOREACH_ARRAY(i, array, num, m, end) \ + for (typeof(array[0]) *i = (array), *end = ({ \ + typeof(num) m = (num); \ + (i && m > 0) ? i + m : NULL; \ + }); end && i < end; i++) + +#define FOREACH_ARRAY(i, array, num) \ + _FOREACH_ARRAY(i, array, num, UNIQ_T(m, UNIQ), UNIQ_T(end, UNIQ)) + +#define FOREACH_ELEMENT(i, array) \ + FOREACH_ARRAY(i, array, ELEMENTSOF(array)) + +#define PTR_TO_SIZE(p) ((size_t) ((uintptr_t) (p))) +#define SIZE_TO_PTR(u) ((void *) ((uintptr_t) (u))) diff --git a/src/libnm-systemd-shared/src/fundamental/sha256.c b/src/libnm-systemd-shared/src/fundamental/sha256-fundamental.c index 84113aed..6682bc87 100644 --- a/src/libnm-systemd-shared/src/fundamental/sha256.c +++ b/src/libnm-systemd-shared/src/fundamental/sha256-fundamental.c @@ -23,15 +23,9 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ -#include <stdbool.h> -#if SD_BOOT -# include "efi-string.h" -#else -# include <string.h> -#endif - #include "macro-fundamental.h" -#include "sha256.h" +#include "memory-util-fundamental.h" +#include "sha256-fundamental.h" #include "unaligned-fundamental.h" #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ diff --git a/src/libnm-systemd-shared/src/fundamental/sha256.h b/src/libnm-systemd-shared/src/fundamental/sha256-fundamental.h index dbb08e35..dbb08e35 100644 --- a/src/libnm-systemd-shared/src/fundamental/sha256.h +++ b/src/libnm-systemd-shared/src/fundamental/sha256-fundamental.h diff --git a/src/libnm-systemd-shared/src/shared/dns-domain.c b/src/libnm-systemd-shared/src/shared/dns-domain.c index a07eaa33..42efd04a 100644 --- a/src/libnm-systemd-shared/src/shared/dns-domain.c +++ b/src/libnm-systemd-shared/src/shared/dns-domain.c @@ -401,9 +401,9 @@ int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, #endif #endif /* NM_IGNORED */ -int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **_ret) { - _cleanup_free_ char *ret = NULL; - size_t n = 0; +int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **ret) { + _cleanup_free_ char *result = NULL; + size_t n_result = 0, n_unescaped = 0; const char *p; bool first = true; int r; @@ -433,17 +433,18 @@ int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **_r break; } + n_unescaped += r + !first; /* Count unescaped length to make max length determination below */ - if (_ret) { - if (!GREEDY_REALLOC(ret, n + !first + DNS_LABEL_ESCAPED_MAX)) + if (ret) { + if (!GREEDY_REALLOC(result, n_result + !first + DNS_LABEL_ESCAPED_MAX)) return -ENOMEM; - r = dns_label_escape(label, r, ret + n + !first, DNS_LABEL_ESCAPED_MAX); + r = dns_label_escape(label, r, result + n_result + !first, DNS_LABEL_ESCAPED_MAX); if (r < 0) return r; if (!first) - ret[n] = '.'; + result[n_result] = '.'; } else { char escaped[DNS_LABEL_ESCAPED_MAX]; @@ -452,45 +453,51 @@ int dns_name_concat(const char *a, const char *b, DNSLabelFlags flags, char **_r return r; } - n += r + !first; + n_result += r + !first; first = false; } finish: - if (n > DNS_HOSTNAME_MAX) - return -EINVAL; + if (n_unescaped == 0) { + /* Nothing appended? If so, generate at least a single dot, to indicate the DNS root domain */ - if (_ret) { - if (n == 0) { - /* Nothing appended? If so, generate at least a single dot, to indicate the DNS root domain */ - if (!GREEDY_REALLOC(ret, 2)) + if (ret) { + if (!GREEDY_REALLOC(result, 2)) /* Room for dot, and already pre-allocate space for the trailing NUL byte at the same time */ return -ENOMEM; - ret[n++] = '.'; - } else { - if (!GREEDY_REALLOC(ret, n + 1)) - return -ENOMEM; + result[n_result++] = '.'; } - ret[n] = 0; - *_ret = TAKE_PTR(ret); + n_unescaped++; + } + + if (n_unescaped > DNS_HOSTNAME_MAX) /* Enforce max length check on unescaped length */ + return -EINVAL; + + if (ret) { + /* Suffix with a NUL byte */ + if (!GREEDY_REALLOC(result, n_result + 1)) + return -ENOMEM; + + result[n_result] = 0; + *ret = TAKE_PTR(result); } return 0; } #if 0 /* NM_IGNORED */ -void dns_name_hash_func(const char *p, struct siphash *state) { +void dns_name_hash_func(const char *name, struct siphash *state) { int r; - assert(p); + assert(name); - for (;;) { + for (const char *p = name;;) { char label[DNS_LABEL_MAX+1]; r = dns_label_unescape(&p, label, sizeof label, 0); if (r < 0) - break; + return string_hash_func(p, state); /* fallback for invalid DNS names */ if (r == 0) break; @@ -516,13 +523,13 @@ int dns_name_compare_func(const char *a, const char *b) { for (;;) { char la[DNS_LABEL_MAX+1], lb[DNS_LABEL_MAX+1]; - if (x == NULL && y == NULL) + if (!x && !y) return 0; r = dns_label_unescape_suffix(a, &x, la, sizeof(la)); q = dns_label_unescape_suffix(b, &y, lb, sizeof(lb)); if (r < 0 || q < 0) - return CMP(r, q); + return strcmp(a, b); /* if not valid DNS labels, then let's compare the whole strings as is */ r = ascii_strcasecmp_nn(la, r, lb, q); if (r != 0) @@ -760,7 +767,7 @@ int dns_name_address(const char *p, int *ret_family, union in_addr_union *ret_ad if (r > 0) { uint8_t a[4]; - for (size_t i = 0; i < ELEMENTSOF(a); i++) { + FOREACH_ELEMENT(i, a) { char label[DNS_LABEL_MAX+1]; r = dns_label_unescape(&p, label, sizeof label, 0); @@ -771,7 +778,7 @@ int dns_name_address(const char *p, int *ret_family, union in_addr_union *ret_ad if (r > 3) return -EINVAL; - r = safe_atou8(label, &a[i]); + r = safe_atou8(label, i); if (r < 0) return r; } @@ -906,6 +913,78 @@ int dns_name_to_wire_format(const char *domain, uint8_t *buffer, size_t len, boo return out - buffer; } +/* Decode a domain name according to RFC 1035 Section 3.1, without compression */ +int dns_name_from_wire_format(const uint8_t **data, size_t *len, char **ret) { + _cleanup_free_ char *domain = NULL; + const uint8_t *optval; + size_t optlen, n = 0; + int r; + + assert(data); + assert(len); + assert(*data || *len == 0); + assert(ret); + + optval = *data; + optlen = *len; + + for (;;) { + const char *label; + uint8_t c; + + /* RFC 4704 § 4: fully qualified domain names include the terminating + * zero-length label, partial names don't. According to the RFC, DHCPv6 + * servers should always send the fully qualified name, but that's not + * true in practice. Also accept partial names. */ + if (optlen == 0) + break; + + /* RFC 1035 § 3.1 total length of encoded name is limited to 255 octets */ + if (*len - optlen > 255) + return -EMSGSIZE; + + c = *optval; + optval++; + optlen--; + + if (c == 0) + /* End label */ + break; + if (c > DNS_LABEL_MAX) + return -EBADMSG; + if (c > optlen) + return -EMSGSIZE; + + /* Literal label */ + label = (const char*) optval; + optval += c; + optlen -= c; + + if (!GREEDY_REALLOC(domain, n + (n != 0) + DNS_LABEL_ESCAPED_MAX)) + return -ENOMEM; + + if (n != 0) + domain[n++] = '.'; + + r = dns_label_escape(label, c, domain + n, DNS_LABEL_ESCAPED_MAX); + if (r < 0) + return r; + + n += r; + } + + if (!GREEDY_REALLOC(domain, n + 1)) + return -ENOMEM; + + domain[n] = '\0'; + + *ret = TAKE_PTR(domain); + *data = optval; + *len = optlen; + + return n; +} + #if 0 /* NM_IGNORED */ static bool srv_type_label_is_valid(const char *label, size_t n) { assert(label); @@ -989,6 +1068,29 @@ bool dns_service_name_is_valid(const char *name) { return true; } +bool dns_subtype_name_is_valid(const char *name) { + size_t l; + + /* This more or less implements RFC 6763, Section 7.2 */ + + if (!name) + return false; + + if (!utf8_is_valid(name)) + return false; + + if (string_has_cc(name, NULL)) + return false; + + l = strlen(name); + if (l <= 0) + return false; + if (l > DNS_LABEL_MAX) + return false; + + return true; +} + int dns_service_join(const char *name, const char *type, const char *domain, char **ret) { char escaped[DNS_LABEL_ESCAPED_MAX]; _cleanup_free_ char *n = NULL; diff --git a/src/libnm-systemd-shared/src/shared/dns-domain.h b/src/libnm-systemd-shared/src/shared/dns-domain.h index a9449410..1cd3c7a5 100644 --- a/src/libnm-systemd-shared/src/shared/dns-domain.h +++ b/src/libnm-systemd-shared/src/shared/dns-domain.h @@ -81,10 +81,12 @@ bool dns_name_is_root(const char *name); bool dns_name_is_single_label(const char *name); int dns_name_to_wire_format(const char *domain, uint8_t *buffer, size_t len, bool canonical); +int dns_name_from_wire_format(const uint8_t **data, size_t *len, char **ret); bool dns_srv_type_is_valid(const char *name); bool dnssd_srv_type_is_valid(const char *name); bool dns_service_name_is_valid(const char *name); +bool dns_subtype_name_is_valid(const char *name); int dns_service_join(const char *name, const char *type, const char *domain, char **ret); int dns_service_split(const char *joined, char **ret_name, char **ret_type, char **ret_domain); diff --git a/src/libnmc-base/nm-client-utils.c b/src/libnmc-base/nm-client-utils.c index 4516bc3b..0c4d53a4 100644 --- a/src/libnmc-base/nm-client-utils.c +++ b/src/libnmc-base/nm-client-utils.c @@ -476,7 +476,7 @@ NM_UTILS_LOOKUP_STR_DEFINE( N_("The device is unmanaged because the link is not initialized by udev")), NM_UTILS_LOOKUP_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_EXPLICIT, N_("The device is unmanaged by explicit user decision (e.g. 'nmcli device " - "set $DEV managed no'")), + "set $DEV managed no')")), NM_UTILS_LOOKUP_ITEM( NM_DEVICE_STATE_REASON_UNMANAGED_USER_SETTINGS, N_("The device is unmanaged by user decision via settings plugin " diff --git a/src/libnmc-base/nm-polkit-listener.c b/src/libnmc-base/nm-polkit-listener.c index c715b049..65e3cfc6 100644 --- a/src/libnmc-base/nm-polkit-listener.c +++ b/src/libnmc-base/nm-polkit-listener.c @@ -574,7 +574,7 @@ create_request(NMPolkitListener *listener, AuthRequest *request; request = g_slice_new(AuthRequest); - *request = (AuthRequest){ + *request = (AuthRequest) { .listener = listener, .dbus_invocation = invocation, .action_id = g_strdup(action_id), diff --git a/src/libnmc-base/nm-secret-agent-simple.c b/src/libnmc-base/nm-secret-agent-simple.c index b6945de7..d8c5344c 100644 --- a/src/libnmc-base/nm-secret-agent-simple.c +++ b/src/libnmc-base/nm-secret-agent-simple.c @@ -164,7 +164,7 @@ _secret_real_new_plain(NMSecretAgentSecretType secret_type, g_object_get(setting, property, &value, NULL); real = g_slice_new(SecretReal); - *real = (SecretReal){ + *real = (SecretReal) { .base.secret_type = secret_type, .base.pretty_name = g_strdup(pretty_name), .base.entry_id = g_strdup_printf("%s.%s", nm_setting_get_name(setting), property), @@ -194,7 +194,7 @@ _secret_real_new_vpn_secret(const char *pretty_name, value = nm_setting_vpn_get_secret(NM_SETTING_VPN(setting), property); real = g_slice_new(SecretReal); - *real = (SecretReal){ + *real = (SecretReal) { .base.secret_type = NM_SECRET_AGENT_SECRET_TYPE_VPN_SECRET, .base.pretty_name = g_strdup(pretty_name), .base.entry_id = @@ -220,7 +220,7 @@ _secret_real_new_wireguard_peer_psk(NMSettingWireGuard *s_wg, nm_assert(public_key); real = g_slice_new(SecretReal); - *real = (SecretReal){ + *real = (SecretReal) { .base.secret_type = NM_SECRET_AGENT_SECRET_TYPE_WIREGUARD_PEER_PSK, .base.pretty_name = g_strdup_printf(_("Preshared-key for %s"), public_key), .base.entry_id = g_strdup_printf(NM_SETTING_WIREGUARD_SETTING_NAME @@ -840,7 +840,7 @@ try_spawn_vpn_auth_helper(RequestData *request, GPtrArray *secrets) auth_dialog_request_str = g_string_free(auth_dialog_request, FALSE); data = g_slice_new(AuthDialogData); - *data = (AuthDialogData){ + *data = (AuthDialogData) { .auth_dialog_response = g_string_new_len(NULL, sizeof(data->read_buf)), .auth_dialog_pid = auth_dialog_pid, .request = request, @@ -1100,7 +1100,7 @@ get_secrets(NMSecretAgentOld *agent, nm_assert(nm_streq(request_id_setting_name, setting_name)); request = g_slice_new(RequestData); - *request = (RequestData){ + *request = (RequestData) { .self = self, .connection = g_object_ref(connection), .setting_name = request_id_setting_name, diff --git a/src/libnmc-setting/nm-meta-setting-base-impl.c b/src/libnmc-setting/nm-meta-setting-base-impl.c index 34a7d22e..37cb61f1 100644 --- a/src/libnmc-setting/nm-meta-setting-base-impl.c +++ b/src/libnmc-setting/nm-meta-setting-base-impl.c @@ -35,6 +35,7 @@ #include "nm-setting-ip-tunnel.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" +#include "nm-setting-ipvlan.h" #include "nm-setting-link.h" #include "nm-setting-loopback.h" #include "nm-setting-macsec.h" @@ -371,6 +372,13 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = { .setting_name = NM_SETTING_IP_TUNNEL_SETTING_NAME, .get_setting_gtype = nm_setting_ip_tunnel_get_type, }, + [NM_META_SETTING_TYPE_IPVLAN] = + { + .meta_type = NM_META_SETTING_TYPE_IPVLAN, + .setting_priority = NM_SETTING_PRIORITY_HW_BASE, + .setting_name = NM_SETTING_IPVLAN_SETTING_NAME, + .get_setting_gtype = nm_setting_ipvlan_get_type, + }, [NM_META_SETTING_TYPE_LINK] = { .meta_type = NM_META_SETTING_TYPE_LINK, @@ -643,6 +651,7 @@ const NMMetaSettingType nm_meta_setting_types_by_priority[] = { NM_META_SETTING_TYPE_HSR, NM_META_SETTING_TYPE_INFINIBAND, NM_META_SETTING_TYPE_IP_TUNNEL, + NM_META_SETTING_TYPE_IPVLAN, NM_META_SETTING_TYPE_LOOPBACK, NM_META_SETTING_TYPE_MACSEC, NM_META_SETTING_TYPE_MACVLAN, @@ -822,7 +831,7 @@ again: for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { const NMMetaSettingInfo *m = &nm_meta_setting_infos[i]; - static_array[i] = (LookupData){ + static_array[i] = (LookupData) { .gtype = m->get_setting_gtype(), .setting_info = m, }; diff --git a/src/libnmc-setting/nm-meta-setting-base-impl.h b/src/libnmc-setting/nm-meta-setting-base-impl.h index 9226183f..c03285eb 100644 --- a/src/libnmc-setting/nm-meta-setting-base-impl.h +++ b/src/libnmc-setting/nm-meta-setting-base-impl.h @@ -128,6 +128,7 @@ typedef enum _nm_packed { NM_META_SETTING_TYPE_IP_TUNNEL, NM_META_SETTING_TYPE_IP4_CONFIG, NM_META_SETTING_TYPE_IP6_CONFIG, + NM_META_SETTING_TYPE_IPVLAN, NM_META_SETTING_TYPE_LINK, NM_META_SETTING_TYPE_LOOPBACK, NM_META_SETTING_TYPE_MACSEC, diff --git a/src/libnmc-setting/nm-meta-setting-desc.c b/src/libnmc-setting/nm-meta-setting-desc.c index 5568c05d..e35db06e 100644 --- a/src/libnmc-setting/nm-meta-setting-desc.c +++ b/src/libnmc-setting/nm-meta-setting-desc.c @@ -11,6 +11,7 @@ #include <arpa/inet.h> #include <linux/if_ether.h> #include <linux/if_infiniband.h> +#include <linux/ethtool.h> #include "libnm-core-aux-intern/nm-common-macros.h" #include "libnm-glib-aux/nm-enum-utils.h" @@ -4459,6 +4460,21 @@ _get_fcn_ethtool(ARGS_GET_FCN) if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) s = gettext(s); return s; + case NM_ETHTOOL_TYPE_FEC: + if (!nm_setting_option_get_uint32(setting, nm_ethtool_data[ethtool_id]->optname, &u32)) { + NM_SET_OUT(out_is_default, TRUE); + return NULL; + } + s = _nm_utils_enum_to_str_full(nm_setting_ethtool_fec_mode_get_type(), + (int) (u32 & INT_MAX), + ", ", + NULL); + if (s == NULL) { + NM_SET_OUT(out_is_default, TRUE); + } + if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY) + s = gettext(s); + return s; case NM_ETHTOOL_TYPE_UNKNOWN: nm_assert_not_reached(); } @@ -4469,9 +4485,11 @@ _get_fcn_ethtool(ARGS_GET_FCN) static gboolean _set_fcn_ethtool(ARGS_SET_FCN) { - NMEthtoolID ethtool_id = property_info->property_typ_data->subtype.ethtool.ethtool_id; - gint64 i64; - NMTernary t; + NMEthtoolID ethtool_id = property_info->property_typ_data->subtype.ethtool.ethtool_id; + gint64 i64; + NMTernary t; + int fec_mode = 0; + gs_free char *invalid_fec_mode = NULL; if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value)) goto do_unset; @@ -4512,6 +4530,30 @@ _set_fcn_ethtool(ARGS_SET_FCN) nm_setting_option_set_boolean(setting, nm_ethtool_data[ethtool_id]->optname, !!t); return TRUE; + case NM_ETHTOOL_TYPE_FEC: + if (_nm_utils_enum_from_str_full(nm_setting_ethtool_fec_mode_get_type(), + value, + &fec_mode, + &invalid_fec_mode, + NULL)) { + nm_setting_option_set_uint32(setting, + NM_ETHTOOL_OPTNAME_FEC_MODE, + (uint32_t) (fec_mode & UINT32_MAX)); + return TRUE; + } else { + gs_free const char **valid_all = NULL; + gs_free const char *valid_str = NULL; + + valid_all = + nm_utils_enum_get_values(nm_setting_ethtool_fec_mode_get_type(), 0, G_MAXUINT); + valid_str = g_strjoinv(",", (char **) valid_all); + nm_utils_error_set(error, + NM_UTILS_ERROR_INVALID_ARGUMENT, + _("'%s' is not valid FEC modes, valid modes are combinations of %s"), + invalid_fec_mode, + valid_str); + return FALSE; + } case NM_ETHTOOL_TYPE_UNKNOWN: nm_assert_not_reached(); } @@ -5661,6 +5703,39 @@ static const NMMetaPropertyInfo *const property_infos_CONNECTION[] = { PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, .property_type = &_pt_gobject_int, ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_IP_PING_TIMEOUT, + .property_type = &_pt_gobject_int, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_IP_PING_ADDRESSES, + .property_type = &_pt_multilist, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( + PROPERTY_TYP_DATA_SUBTYPE (multilist, + .add_fcn = MULTILIST_ADD_FCN (NMSettingConnection, nm_setting_connection_add_ip_ping_address), + .remove_by_idx_fcn_u32 = MULTILIST_REMOVE_BY_IDX_FCN_U32 (NMSettingConnection, nm_setting_connection_remove_ip_ping_address), + .remove_by_value_fcn = MULTILIST_REMOVE_BY_VALUE_FCN (NMSettingConnection, nm_setting_connection_remove_ip_ping_address_by_value), + .clear_all_fcn = OBJLIST_CLEAR_ALL_FCN (NMSettingConnection, nm_setting_connection_clear_ip_ping_addresses), + .strsplit_with_spaces = TRUE, + ), + .list_items_doc_format = NM_META_PROPERTY_TYPE_FORMAT_IPV4_IPV6, + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_IP_PING_ADDRESSES_REQUIRE_ALL, + .property_type = &_pt_gobject_enum, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( + PROPERTY_TYP_DATA_SUBTYPE (gobject_enum, + .value_infos = ENUM_VALUE_INFOS( + { + .value = 0, + .nick = "no", + }, + { + .value = 1, + .nick = "yes", + }, + ), + ), + ), + ), PROPERTY_INFO_WITH_DESC (NM_SETTING_CONNECTION_METERED, .describe_message = N_("Enter a value which indicates whether the connection is subject to a data\n" @@ -5956,6 +6031,15 @@ static const NMMetaPropertyInfo *const property_infos_ETHTOOL[] = { PROPERTY_INFO_ETHTOOL (CHANNELS_TX), PROPERTY_INFO_ETHTOOL (CHANNELS_OTHER), PROPERTY_INFO_ETHTOOL (CHANNELS_COMBINED), + PROPERTY_INFO (NM_ETHTOOL_OPTNAME_FEC_MODE, + "The Forward Error Correction(FEC) encoding modes to set. " + "Not all devices support all options. " + "May be any combination of auto, off, rs, baser, llrs.", + .property_type = &_pt_ethtool, + .property_typ_data = + DEFINE_PROPERTY_TYP_DATA_SUBTYPE + (ethtool, .ethtool_id = NM_ETHTOOL_ID_FEC_MODE) + ), NULL, }; @@ -6045,6 +6129,34 @@ static const NMMetaPropertyInfo *const property_infos_GSM[] = { PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_INITIAL_EPS_BEARER_APN, .property_type = &_pt_gobject_string, ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_INITIAL_EPS_BEARER_USERNAME, + .property_type = &_pt_gobject_string, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_INITIAL_EPS_BEARER_PASSWORD, + .is_secret = TRUE, + .property_type = &_pt_gobject_string, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_INITIAL_EPS_BEARER_PASSWORD_FLAGS, + .property_type = &_pt_gobject_secret_flags, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_INITIAL_EPS_BEARER_NOAUTH, + .property_type = &_pt_gobject_bool, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_EAP, + .property_type = &_pt_gobject_bool, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_PAP, + .property_type = &_pt_gobject_bool, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_CHAP, + .property_type = &_pt_gobject_bool, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_MSCHAP, + .property_type = &_pt_gobject_bool, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_MSCHAPV2, + .property_type = &_pt_gobject_bool, + ), NULL }; @@ -6077,7 +6189,6 @@ static const NMMetaPropertyInfo *const property_infos_HSR[] = { NULL }; - #undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_HOSTNAME static const NMMetaPropertyInfo *const property_infos_HOSTNAME[] = { @@ -6317,6 +6428,9 @@ static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = { PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_SEND_RELEASE, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_SEND_RELEASE, .property_type = &_pt_gobject_ternary, ), + PROPERTY_INFO (NM_SETTING_IP_CONFIG_ROUTED_DNS, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTED_DNS, + .property_type = &_pt_gobject_enum, + ), PROPERTY_INFO (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, .property_type = &_pt_gobject_bool, ), @@ -6342,6 +6456,23 @@ static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = { PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME, .property_type = &_pt_gobject_bool, ), + PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME_V2, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME_V2, + .property_type = &_pt_gobject_enum, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( + PROPERTY_TYP_DATA_SUBTYPE (gobject_enum, + .value_infos = ENUM_VALUE_INFOS( + { + .value = 0, + .nick = "no", + }, + { + .value = 1, + .nick = "yes", + }, + ), + ), + ), + ), PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, .property_type = &_pt_gobject_string, ), @@ -6395,6 +6526,9 @@ static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = { PROPERTY_INFO_WITH_DESC (NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER, .property_type = &_pt_gobject_string, ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_IP4_CONFIG_DHCP_IPV6_ONLY_PREFERRED, + .property_type = &_pt_gobject_enum, + ), PROPERTY_INFO_WITH_DESC (NM_SETTING_IP4_CONFIG_LINK_LOCAL, .property_type = &_pt_gobject_enum, .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( @@ -6420,6 +6554,24 @@ static const NMMetaPropertyInfo *const property_infos_IP4_CONFIG[] = { PROPERTY_INFO (NM_SETTING_IP_CONFIG_AUTO_ROUTE_EXT_GW, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_AUTO_ROUTE_EXT_GW, .property_type = &_pt_gobject_ternary, ), + PROPERTY_INFO (NM_SETTING_IP_CONFIG_SHARED_DHCP_RANGE, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_SHARED_DHCP_RANGE, + .property_type = &_pt_gobject_string, + ), + PROPERTY_INFO (NM_SETTING_IP_CONFIG_SHARED_DHCP_LEASE_TIME, DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_SHARED_DHCP_LEASE_TIME, + .property_type = &_pt_gobject_int, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_int, + .value_infos = INT_VALUE_INFOS ( + { + .value.i64 = 0, + .nick = "default", + }, + { + .value.i64 = G_MAXINT32, + .nick = "infinity", + }, + ), + ), + ), NULL }; @@ -6590,6 +6742,9 @@ static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = { PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_SEND_RELEASE, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_SEND_RELEASE, .property_type = &_pt_gobject_ternary, ), + PROPERTY_INFO (NM_SETTING_IP_CONFIG_ROUTED_DNS, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTED_DNS, + .property_type = &_pt_gobject_enum, + ), PROPERTY_INFO (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, .property_type = &_pt_gobject_bool, ), @@ -6700,6 +6855,23 @@ static const NMMetaPropertyInfo *const property_infos_IP6_CONFIG[] = { PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_SEND_HOSTNAME, .property_type = &_pt_gobject_bool, ), + PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME_V2, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_SEND_HOSTNAME_V2, + .property_type = &_pt_gobject_enum, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( + PROPERTY_TYP_DATA_SUBTYPE (gobject_enum, + .value_infos = ENUM_VALUE_INFOS( + { + .value = 0, + .nick = "no", + }, + { + .value = 1, + .nick = "yes", + }, + ), + ), + ), + ), PROPERTY_INFO (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_HOSTNAME, .property_type = &_pt_gobject_string, ), @@ -6800,6 +6972,37 @@ static const NMMetaPropertyInfo *const property_infos_IP_TUNNEL[] = { }; #undef _CURRENT_NM_META_SETTING_TYPE +#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_IPVLAN +static const NMMetaPropertyInfo *const property_infos_IPVLAN[] = { + PROPERTY_INFO_WITH_DESC (NM_SETTING_IPVLAN_PARENT, + .is_cli_option = TRUE, + .property_alias = "dev", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = N_("IPVLAN parent device or connection UUID"), + .property_type = &_pt_gobject_devices, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_IPVLAN_MODE, + .is_cli_option = TRUE, + .property_alias = "mode", + .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, + .prompt = NM_META_TEXT_PROMPT_IPVLAN_MODE, + .property_type = &_pt_gobject_enum, + .property_typ_data = DEFINE_PROPERTY_TYP_DATA_SUBTYPE (gobject_enum, + .get_gtype = nm_setting_ipvlan_mode_get_type, + .min = NM_SETTING_IPVLAN_MODE_UNKNOWN + 1, + .max = G_MAXINT, + ), + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_IPVLAN_PRIVATE, + .property_type = &_pt_gobject_bool, + ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_IPVLAN_VEPA, + .property_type = &_pt_gobject_bool, + ), + NULL +}; + +#undef _CURRENT_NM_META_SETTING_TYPE #define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_LOOPBACK static const NMMetaPropertyInfo *const property_infos_LOOPBACK[] = { PROPERTY_INFO_WITH_DESC (NM_SETTING_LOOPBACK_MTU, @@ -8713,6 +8916,7 @@ _setting_init_fcn_wireless (ARGS_SETTING_INIT_FCN) #define SETTING_PRETTY_NAME_IP4_CONFIG N_("IPv4 protocol") #define SETTING_PRETTY_NAME_IP6_CONFIG N_("IPv6 protocol") #define SETTING_PRETTY_NAME_IP_TUNNEL N_("IP-tunnel settings") +#define SETTING_PRETTY_NAME_IPVLAN N_("IPVLAN settings") #define SETTING_PRETTY_NAME_LINK N_("Link settings") #define SETTING_PRETTY_NAME_LOOPBACK N_("Loopback settings") #define SETTING_PRETTY_NAME_MACSEC N_("MACsec connection") @@ -8881,6 +9085,14 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), ), ), + SETTING_INFO (IPVLAN, + .valid_parts = NM_META_SETTING_VALID_PARTS ( + NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), + NM_META_SETTING_VALID_PART_ITEM (IPVLAN, TRUE), + NM_META_SETTING_VALID_PART_ITEM (WIRED, FALSE), + NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE), + ), + ), SETTING_INFO (LINK), SETTING_INFO (LOOPBACK, .valid_parts = NM_META_SETTING_VALID_PARTS ( diff --git a/src/libnmc-setting/nm-meta-setting-desc.h b/src/libnmc-setting/nm-meta-setting-desc.h index 21d91382..fa09fbe6 100644 --- a/src/libnmc-setting/nm-meta-setting-desc.h +++ b/src/libnmc-setting/nm-meta-setting-desc.h @@ -69,6 +69,8 @@ struct _NMDevice; #define NM_META_TEXT_PROMPT_IP_TUNNEL_MODE N_("IP Tunnel mode") +#define NM_META_TEXT_PROMPT_IPVLAN_MODE N_("IPVLAN mode") + #define NM_META_TEXT_PROMPT_MACVLAN_MODE N_("MACVLAN mode") #define NM_META_TEXT_PROMPT_MACSEC_MODE N_("MACsec mode") @@ -195,6 +197,7 @@ typedef enum _nm_packed { NM_META_PROPERTY_TYPE_FORMAT_MAC, NM_META_PROPERTY_TYPE_FORMAT_IPV4, NM_META_PROPERTY_TYPE_FORMAT_IPV6, + NM_META_PROPERTY_TYPE_FORMAT_IPV4_IPV6, NM_META_PROPERTY_TYPE_FORMAT_MTU, NM_META_PROPERTY_TYPE_FORMAT_BYTES, NM_META_PROPERTY_TYPE_FORMAT_PATH, diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in index 731f32a7..dd719afa 100644 --- a/src/libnmc-setting/settings-docs.h.in +++ b/src/libnmc-setting/settings-docs.h.in @@ -12,6 +12,9 @@ #define DESCRIBE_DOC_NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT N_("If greater than zero, delay success of IP addressing until either the timeout is reached, or an IP gateway replies to a ping.") #define DESCRIBE_DOC_NM_SETTING_CONNECTION_ID N_("A human readable unique identifier for the connection, like \"Work Wi-Fi\" or \"T-Mobile 3G\".") #define DESCRIBE_DOC_NM_SETTING_CONNECTION_INTERFACE_NAME N_("The name of the network interface this connection is bound to. If not set, then the connection can be attached to any interface of the appropriate type (subject to restrictions imposed by other settings). For software devices this specifies the name of the created device. For connection types where interface names cannot easily be made persistent (e.g. mobile broadband or USB Ethernet), this property should not be used. Setting this property restricts the interfaces a connection can be used with, and if interface names change or are reordered the connection may be applied to the wrong interface.") +#define DESCRIBE_DOC_NM_SETTING_CONNECTION_IP_PING_ADDRESSES N_("The property specifies a list of target IP addresses for pinging. When multiple targets are set, NetworkManager will start multiple ping processes in parallel. This property can only be set if connection.ip-ping-timeout is set. The ip-ping-timeout is used to delay the success of IP addressing until either the specified timeout (in seconds) is reached, or an target IP address replies to a ping. Configuring \"ip-ping-addresses\" may delay reaching the systemd's network-online.target due to waiting for the ping operations to complete or timeout.") +#define DESCRIBE_DOC_NM_SETTING_CONNECTION_IP_PING_ADDRESSES_REQUIRE_ALL N_("The property determines whether it is sufficient for any ping check to succeed among \"ip-ping-addresses\", or if all ping checks must succeed for \"ip-ping-addresses\".") +#define DESCRIBE_DOC_NM_SETTING_CONNECTION_IP_PING_TIMEOUT N_("If greater than zero, delay success of IP addressing until either the specified timeout (in seconds) is reached, or a target IP address replies to a ping. The property specifies the timeout for the \"ip-ping-addresses\". This property is incompatible with \"gateway-ping-timeout\", you cannot set these two properties at the same time.") #define DESCRIBE_DOC_NM_SETTING_CONNECTION_LLDP N_("Whether LLDP is enabled for the connection.") #define DESCRIBE_DOC_NM_SETTING_CONNECTION_LLMNR N_("Whether Link-Local Multicast Name Resolution (LLMNR) is enabled for the connection. LLMNR is a protocol based on the Domain Name System (DNS) packet format that allows both IPv4 and IPv6 hosts to perform name resolution for hosts on the same local link. The permitted values are: \"yes\" (2) register hostname and resolving for the connection, \"no\" (0) disable LLMNR for the interface, \"resolve\" (1) do not register hostname but allow resolving of LLMNR host names If unspecified, \"default\" ultimately depends on the DNS plugin (which for systemd-resolved currently means \"yes\"). This feature requires a plugin which supports LLMNR. Otherwise, the setting has no effect. One such plugin is dns-systemd-resolved.") #define DESCRIBE_DOC_NM_SETTING_CONNECTION_MASTER N_("Interface name of the controller device or UUID of the controller connection. Deprecated 1.46. Use \"controller\" instead, this is just an alias.") @@ -149,6 +152,15 @@ #define DESCRIBE_DOC_NM_SETTING_GSM_HOME_ONLY N_("When TRUE, only connections to the home network will be allowed. Connections to roaming networks will not be made.") #define DESCRIBE_DOC_NM_SETTING_GSM_INITIAL_EPS_BEARER_APN N_("For LTE modems, this sets the APN for the initial EPS bearer that is set up when attaching to the network. Setting this parameter implies initial-eps-bearer-configure to be TRUE.") #define DESCRIBE_DOC_NM_SETTING_GSM_INITIAL_EPS_BEARER_CONFIGURE N_("For LTE modems, this setting determines whether the initial EPS bearer shall be configured when bringing up the connection. It is inferred TRUE if initial-eps-bearer-apn is set.") +#define DESCRIBE_DOC_NM_SETTING_GSM_INITIAL_EPS_BEARER_NOAUTH N_("For LTE modems, this sets NOAUTH authentication method for the initial EPS bearer that is set up when attaching to the network. If TRUE, do not require the other side to authenticate itself to the client. If FALSE, require authentication from the remote side. In almost all cases, this should be TRUE.") +#define DESCRIBE_DOC_NM_SETTING_GSM_INITIAL_EPS_BEARER_PASSWORD N_("For LTE modems, this sets the password for the initial EPS bearer that is set up when attaching to the network. Setting this parameter implies initial-eps-bearer-configure to be TRUE.") +#define DESCRIBE_DOC_NM_SETTING_GSM_INITIAL_EPS_BEARER_PASSWORD_FLAGS N_("Flags indicating how to handle the \"initial-eps-bearer-password\" property.") +#define DESCRIBE_DOC_NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_CHAP N_("For LTE modems, this disables CHAP authentication method for the initial EPS bearer that is set up when attaching to the network.") +#define DESCRIBE_DOC_NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_EAP N_("For LTE modems, this disables EAP authentication method for the initial EPS bearer that is set up when attaching to the network.") +#define DESCRIBE_DOC_NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_MSCHAP N_("For LTE modems, this disables MSCHAP authentication method for the initial EPS bearer that is set up when attaching to the network.") +#define DESCRIBE_DOC_NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_MSCHAPV2 N_("For LTE modems, this disables MSCHAPV2 authentication method for the initial EPS bearer that is set up when attaching to the network.") +#define DESCRIBE_DOC_NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_PAP N_("For LTE modems, this disables PAP authentication method for the initial EPS bearer that is set up when attaching to the network.") +#define DESCRIBE_DOC_NM_SETTING_GSM_INITIAL_EPS_BEARER_USERNAME N_("For LTE modems, this sets the username for the initial EPS bearer that is set up when attaching to the network. Setting this parameter implies initial-eps-bearer-configure to be TRUE.") #define DESCRIBE_DOC_NM_SETTING_GSM_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames.") #define DESCRIBE_DOC_NM_SETTING_GSM_NETWORK_ID N_("The Network ID (GSM LAI format, ie MCC-MNC) to force specific network registration. If the Network ID is specified, NetworkManager will attempt to force the device to register only on the specified network. This can be used to ensure that the device does not roam when direct roaming control of the device is not otherwise possible.") #define DESCRIBE_DOC_NM_SETTING_GSM_NUMBER N_("Legacy setting that used to help establishing PPP data sessions for GSM-based modems.") @@ -177,19 +189,21 @@ #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME N_("If the \"dhcp-send-hostname\" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and \"dhcp-fqdn\" are mutually exclusive and cannot be set at the same time.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME_FLAGS N_("Flags for the DHCP hostname and FQDN. Currently, this property only includes flags to control the FQDN flags set in the DHCP FQDN option. Supported FQDN flags are \"fqdn-serv-update\" (0x1), \"fqdn-encoded\" (0x2) and \"fqdn-no-update\" (0x4). When no FQDN flag is set and \"fqdn-clear-flags\" (0x8) is set, the DHCP FQDN option will contain no flag. Otherwise, if no FQDN flag is set and \"fqdn-clear-flags\" (0x8) is not set, the standard FQDN flags are set in the request: \"fqdn-serv-update\" (0x1), \"fqdn-encoded\" (0x2) for IPv4 and \"fqdn-serv-update\" (0x1) for IPv6. When this property is set to the default value \"none\" (0x0), a global default is looked up in NetworkManager configuration. If that value is unset or also \"none\" (0x0), then the standard FQDN flags described above are sent in the DHCP requests.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_IAID N_("A string containing the \"Identity Association Identifier\" (IAID) used by the DHCP client. The string can be a 32-bit number (either decimal, hexadecimal or as colon separated hexadecimal numbers). Alternatively it can be set to the special values \"mac\", \"perm-mac\", \"ifname\" or \"stable\". When set to \"mac\" (or \"perm-mac\"), the last 4 bytes of the current (or permanent) MAC address are used as IAID. When set to \"ifname\", the IAID is computed by hashing the interface name. The special value \"stable\" can be used to generate an IAID based on the stable-id (see connection.stable-id), a per-host key and the interface name. When the property is unset, the value from global configuration is used; if no global default is set then the IAID is assumed to be \"ifname\". For DHCPv4, the IAID is only used with \"ipv4.dhcp-client-id\" values \"duid\" and \"ipv6-duid\" to generate the client-id. For DHCPv6, note that at the moment this property is only supported by the \"internal\" DHCPv6 plugin. The \"dhclient\" DHCPv6 plugin always derives the IAID from the MAC address. The actually used DHCPv6 IAID for a currently activated interface is exposed in the lease information of the device.") +#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_IPV6_ONLY_PREFERRED N_("Controls the \"IPv6-Only Preferred\" DHCPv4 option (RFC 8925). When set to \"yes\" (1), the host adds the option to the parameter request list; if the DHCP server sends the option back, the host stops the DHCP client for the time interval specified in the option. Enable this feature if the host supports an IPv6-only mode, i.e. either all applications are IPv6-only capable or there is a form of 464XLAT deployed. When set to \"default\" (-1), the actual value is looked up in the global configuration; if not specified, it defaults to \"no\" (0). If the connection has IPv6 method set to \"disabled\", this property does not have effect and the \"IPv6-Only Preferred\" option is always disabled.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_REJECT_SERVERS N_("Array of servers from which DHCP offers must be rejected. This property is useful to avoid getting a lease from misconfigured or rogue servers. For DHCPv4, each element must be an IPv4 address, optionally followed by a slash and a prefix length (e.g. \"192.168.122.0/24\"). This property is currently not implemented for DHCPv6.") -#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME N_("If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the \"dhcp-hostname\" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent.") +#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME N_("Since 1.52 this property is deprecated and is only used as fallback value for dhcp-send-hostname if it's set to 'default'. This is only done to avoid breaking existing configurations, the new property should be used from now on.") +#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME_V2 N_("If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the dhcp-hostname property is NULL and this property is TRUE, the current persistent hostname of the computer is sent. The default value is default (-1). In this case the global value from NetworkManager configuration is looked up. If it's not set, the value from dhcp-send-hostname-deprecated, which defaults to TRUE, is used for backwards compatibility. In the future this will change and, in absence of a global default, it will always fallback to TRUE.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_SEND_RELEASE N_("Whether the DHCP client will send RELEASE message when bringing the connection down. The default value is \"default\" (-1). When the default value is specified, then the global value from NetworkManager configuration is looked up, if not set, it is considered as FALSE.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT N_("A timeout for a DHCP transaction in seconds. If zero (the default), a globally configured default is used. If still unspecified, a device specific timeout is used (usually 45 seconds). Set to 2147483647 (MAXINT32) for infinity.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_VENDOR_CLASS_IDENTIFIER N_("The Vendor Class Identifier DHCP option (60). Special characters in the data string may be escaped using C-style escapes, nevertheless this property cannot contain nul bytes. If the per-profile value is unspecified (the default), a global connection default gets consulted. If still unspecified, the DHCP option is not sent to the server.") -#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS N_("Array of IP addresses of DNS servers. For DoT (DNS over TLS), the SNI server name can be specified by appending \"#example.com\" to the IP address of the DNS server. This currently only has effect when using systemd-resolved.") +#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS N_("Array of DNS servers. Each server can be specified either as a plain IP address (optionally followed by a \"#\" and the SNI server name for DNS over TLS) or with a URI syntax. When it is specified as an URI, the following forms are supported: dns+udp://ADDRESS[:PORT], dns+tls://ADDRESS[:PORT][SERVERNAME] . When using the URI syntax, IPv6 addresses must be enclosed in square brackets ('[', ']').") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_OPTIONS N_("DNS options for /etc/resolv.conf as described in resolv.conf(5) manual. The currently supported options are \"attempts\", \"debug\", \"edns0\", \"ndots\", \"no-aaaa\", \"no-check-names\", \"no-reload\", \"no-tld-query\", \"rotate\", \"single-request\", \"single-request-reopen\", \"timeout\", \"trust-ad\", \"use-vc\". See the resolv.conf(5) manual. Note that there is a distinction between an unset (default) list and an empty list. In nmcli, to unset the list set the value to \"\". To set an empty list, set it to \" \". Currently, an unset list has the same meaning as an empty list. That might change in the future. The \"trust-ad\" setting is only honored if the profile contributes name servers to resolv.conf, and if all contributing profiles have \"trust-ad\" enabled. When using a caching DNS plugin (dnsmasq or systemd-resolved in NetworkManager.conf) then \"edns0\" and \"trust-ad\" are automatically added. The valid \"ipv4.dns-options\" and \"ipv6.dns-options\" get merged together.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_PRIORITY N_("DNS servers priority. The relative priority for DNS servers specified by this setting. A lower numerical value is better (higher priority). Negative values have the special effect of excluding other configurations with a greater numerical priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. To avoid all DNS leaks, set the priority of the profile that should be used to the most negative value of all active connections profiles. Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. Note that commonly the resolver tries name servers in /etc/resolv.conf in the order listed, proceeding with the next server in the list on failure. See for example the \"rotate\" option of the dns-options setting. If there are any negative DNS priorities, then only name servers from the devices with that lowest priority will be considered. When using a DNS resolver that supports Conditional Forwarding or Split DNS (with dns=dnsmasq or dns=systemd-resolved settings), each connection is used to query domains in its search list. The search domains determine which name servers to ask, and the DNS priority is used to prioritize name servers based on the domain. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the best priority (lowest numerical value) wins. If a sub domain is configured on another interface it will be accepted regardless the priority, unless parent domain on the other interface has a negative priority, which causes the sub domain to be shadowed. With Split DNS one can avoid undesired DNS leaks by properly configuring DNS priorities and the search domains, so that only name servers of the desired interface are configured.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS_SEARCH N_("List of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names. When using a DNS plugin that supports Conditional Forwarding or Split DNS, then the search domains specify which name servers to query. This makes the behavior different from running with plain /etc/resolv.conf. For more information see also the dns-priority setting. When set on a profile that also enabled DHCP, the DNS search list received automatically (option 119 for DHCPv4 and option 24 for DHCPv6) gets merged with the manual list. This can be prevented by setting \"ignore-auto-dns\". Note that if no DNS searches are configured, the fallback will be derived from the domain from DHCP (option 15).") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_GATEWAY N_("The gateway associated with this configuration. This is only meaningful if \"addresses\" is also set. Setting the gateway causes NetworkManager to configure a standard default route with the gateway as next hop. This is ignored if \"never-default\" is set. An alternative is to configure the default route explicitly with a manual route and /0 as prefix length. Note that the gateway usually conflicts with routing that NetworkManager configures for WireGuard interfaces, so usually it should not be set in that case. See \"ip4-auto-default-route\".") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured name servers and search domains are ignored and only name servers and search domains specified in the \"dns\" and \"dns-search\" properties, if any, are used.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES N_("When \"method\" is set to \"auto\" and this property to TRUE, automatically configured routes are ignored and only routes specified in the \"routes\" property, if any, are used.") -#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_LINK_LOCAL N_("Enable and disable the IPv4 link-local configuration independently of the ipv4.method configuration. This allows a link-local address (169.254.x.y/16) to be obtained in addition to other addresses, such as those manually configured or obtained from a DHCP server. When set to \"auto\", the value is dependent on \"ipv4.method\". When set to \"default\", it honors the global connection default, before falling back to \"auto\". Note that if \"ipv4.method\" is \"disabled\", then link local addressing is always disabled too. The default is \"default\".") +#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_LINK_LOCAL N_("Enable and disable the IPv4 link-local configuration independently of the ipv4.method configuration. This allows a link-local address (169.254.x.y/16) to be obtained in addition to other addresses, such as those manually configured or obtained from a DHCP server. When set to \"auto\", the value is dependent on \"ipv4.method\". When set to \"default\", it honors the global connection default, before falling back to \"auto\". Note that if \"ipv4.method\" is \"disabled\", then link local addressing is always disabled too. The default is \"default\". Since 1.52, when set to \"fallback\", a link-local address is obtained if no other IPv4 address is set.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_MAY_FAIL N_("If TRUE, allow overall network configuration to proceed even if the configuration specified by this property times out. Note that at least one IP configuration must succeed or overall network configuration will still fail. For example, in IPv6-only networks, setting this property to TRUE on the NMSettingIP4Config allows the overall network configuration to succeed if IPv4 configuration fails but IPv6 configuration completes successfully.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_METHOD N_("The IPv4 connection method.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_NEVER_DEFAULT N_("If TRUE, this connection will never be the default connection for this IP type, meaning it will never be assigned the default route by NetworkManager.") @@ -197,8 +211,11 @@ #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_REQUIRED_TIMEOUT N_("The minimum time interval in milliseconds for which dynamic IP configuration should be tried before the connection succeeds. This property is useful for example if both IPv4 and IPv6 are enabled and are allowed to fail. Normally the connection succeeds as soon as one of the two address families completes; by setting a required timeout for e.g. IPv4, one can ensure that even if IP6 succeeds earlier than IPv4, NetworkManager waits some time for IPv4 before the connection becomes active. Note that if \"may-fail\" is FALSE for the same address family, this property has no effect as NetworkManager needs to wait for the full DHCP timeout. A zero value means that no required timeout is present, -1 means the default value (either configuration ipvx.required-timeout override or zero).") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTE_METRIC N_("The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is chosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTE_TABLE N_("Enable policy routing (source routing) and set the routing table used when adding routes. This affects all routes, including device-routes, IPv4LL, DHCP, SLAAC, default-routes and static routes. But note that static routes can individually overwrite the setting by explicitly specifying a non-zero routing table. If the table setting is left at zero, it is eligible to be overwritten via global configuration. If the property is zero even after applying the global configuration value, policy routing is disabled for the address family of this connection. Policy routing disabled means that NetworkManager will add all routes to the main table (except static routes that explicitly configure a different table). Additionally, NetworkManager will not delete any extraneous routes from tables except the main table. This is to preserve backward compatibility for users who manage routing tables outside of NetworkManager.") +#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTED_DNS N_("Whether to add routes for DNS servers. When enabled, NetworkManager adds a route for each DNS server that is associated with this connection either statically (defined in the connection profile) or dynamically (for example, retrieved via DHCP). The route guarantees that the DNS server is reached via this interface. When set to \"default\" (-1), the value from global configuration is used; if no global default is defined, this feature is disabled.") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTES N_("A list of IPv4 destination addresses, prefix length, optional IPv4 next hop addresses, optional route metric, optional attribute. The valid syntax is: \"ip[/prefix] [next-hop] [metric] [attribute=val]...[,ip[/prefix]...]\". For example \"192.0.2.0/24 10.1.1.1 77, 198.51.100.0/24\".") #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ROUTING_RULES N_("A comma separated list of routing rules for policy routing.") +#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_SHARED_DHCP_LEASE_TIME N_("This option allows you to specify a custom DHCP lease time for the shared connection method in seconds. The value should be either a number between 120 and 31536000 (one year) If this option is not specified, 3600 (one hour) is used. Special values are 0 for default value of 1 hour and 2147483647 (MAXINT32) for infinite lease time.") +#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_SHARED_DHCP_RANGE N_("This option allows you to specify a custom DHCP range for the shared connection method. The value is expected to be in `<START_ADDRESS>,<END_ADDRESS>` format. The range should be part of network set by ipv4.address option and it should not contain network address or broadcast address. If this option is not specified, the DHCP range will be automatically determined based on the interface address. The range will be selected to be adjacent to the interface address, either before or after it, with the larger possible range being preferred. The range will be adjusted to fill the available address space, except for networks with a prefix length greater than 24, which will be treated as if they have a prefix length of 24.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE N_("Configure method for creating the IPv6 interface identifier of addresses with RFC4862 IPv6 Stateless Address Autoconfiguration and Link Local addresses. The permitted values are: \"eui64\" (0), \"stable-privacy\" (1), \"default\" (3) or \"default-or-eui64\" (2). If the property is set to \"eui64\", the addresses will be generated using the interface token derived from hardware address. This makes the host part of the address to stay constant, making it possible to track the host's presence when it changes networks. The address changes when the interface hardware is replaced. If a duplicate address is detected, there is also no fallback to generate another address. When configured, the \"ipv6.token\" is used instead of the MAC address to generate addresses for stateless autoconfiguration. If the property is set to \"stable-privacy\", the interface identifier is generated as specified by RFC7217. This works by hashing a host specific key (see NetworkManager(8) manual), the interface name, the connection's \"connection.stable-id\" property and the address prefix. This improves privacy by making it harder to use the address to track the host's presence and the address is stable when the network interface hardware is replaced. The special values \"default\" and \"default-or-eui64\" will fallback to the global connection default as documented in the NetworkManager.conf(5) manual. If the global default is not specified, the fallback value is \"stable-privacy\" or \"eui64\", respectively. If not specified, when creating a new profile the default is \"default\". Note that this setting is distinct from the Privacy Extensions as configured by \"ip6-privacy\" property and it does not affect the temporary addresses configured with this option.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ADDRESSES N_("A list of IPv6 addresses and their prefix length. Multiple addresses can be separated by comma. For example \"2001:db8:85a3::8a2e:370:7334/64, 2001:db8:85a3::5/64\". The addresses are listed in decreasing priority, meaning the first address will be the primary address. This can make a difference with IPv6 source address selection (RFC 6724, section 5).") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_AUTO_ROUTE_EXT_GW N_("VPN connections will default to add the route automatically unless this setting is set to FALSE. For other connection types, adding such an automatic route is currently not supported and setting this to TRUE has no effect.") @@ -210,10 +227,11 @@ #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_IAID N_("A string containing the \"Identity Association Identifier\" (IAID) used by the DHCP client. The string can be a 32-bit number (either decimal, hexadecimal or as colon separated hexadecimal numbers). Alternatively it can be set to the special values \"mac\", \"perm-mac\", \"ifname\" or \"stable\". When set to \"mac\" (or \"perm-mac\"), the last 4 bytes of the current (or permanent) MAC address are used as IAID. When set to \"ifname\", the IAID is computed by hashing the interface name. The special value \"stable\" can be used to generate an IAID based on the stable-id (see connection.stable-id), a per-host key and the interface name. When the property is unset, the value from global configuration is used; if no global default is set then the IAID is assumed to be \"ifname\". For DHCPv4, the IAID is only used with \"ipv4.dhcp-client-id\" values \"duid\" and \"ipv6-duid\" to generate the client-id. For DHCPv6, note that at the moment this property is only supported by the \"internal\" DHCPv6 plugin. The \"dhclient\" DHCPv6 plugin always derives the IAID from the MAC address. The actually used DHCPv6 IAID for a currently activated interface is exposed in the lease information of the device.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_PD_HINT N_("A IPv6 address followed by a slash and a prefix length. If set, the value is sent to the DHCPv6 server as hint indicating the prefix delegation (IA_PD) we want to receive. To only hint a prefix length without prefix, set the address part to the zero address (for example \"::/60\").") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_REJECT_SERVERS N_("Array of servers from which DHCP offers must be rejected. This property is useful to avoid getting a lease from misconfigured or rogue servers. For DHCPv4, each element must be an IPv4 address, optionally followed by a slash and a prefix length (e.g. \"192.168.122.0/24\"). This property is currently not implemented for DHCPv6.") -#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_SEND_HOSTNAME N_("If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the \"dhcp-hostname\" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent.") +#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_SEND_HOSTNAME N_("Since 1.52 this property is deprecated and is only used as fallback value for dhcp-send-hostname if it's set to 'default'. This is only done to avoid breaking existing configurations, the new property should be used from now on.") +#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_SEND_HOSTNAME_V2 N_("If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the dhcp-hostname property is NULL and this property is TRUE, the current persistent hostname of the computer is sent. The default value is default (-1). In this case the global value from NetworkManager configuration is looked up. If it's not set, the value from dhcp-send-hostname-deprecated, which defaults to TRUE, is used for backwards compatibility. In the future this will change and, in absence of a global default, it will always fallback to TRUE.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_SEND_RELEASE N_("Whether the DHCP client will send RELEASE message when bringing the connection down. The default value is \"default\" (-1). When the default value is specified, then the global value from NetworkManager configuration is looked up, if not set, it is considered as FALSE.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_TIMEOUT N_("A timeout for a DHCP transaction in seconds. If zero (the default), a globally configured default is used. If still unspecified, a device specific timeout is used (usually 45 seconds). Set to 2147483647 (MAXINT32) for infinity.") -#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS N_("Array of IP addresses of DNS servers. For DoT (DNS over TLS), the SNI server name can be specified by appending \"#example.com\" to the IP address of the DNS server. This currently only has effect when using systemd-resolved.") +#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS N_("Array of DNS servers. Each server can be specified either as a plain IP address (optionally followed by a \"#\" and the SNI server name for DNS over TLS) or with a URI syntax. When it is specified as an URI, the following forms are supported: dns+udp://ADDRESS[:PORT], dns+tls://ADDRESS[:PORT][SERVERNAME] . When using the URI syntax, IPv6 addresses must be enclosed in square brackets ('[', ']').") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_OPTIONS N_("DNS options for /etc/resolv.conf as described in resolv.conf(5) manual. The currently supported options are \"attempts\", \"debug\", \"edns0\", \"ndots\", \"no-aaaa\", \"no-check-names\", \"no-reload\", \"no-tld-query\", \"rotate\", \"single-request\", \"single-request-reopen\", \"timeout\", \"trust-ad\", \"use-vc\" and \"inet6\", \"ip6-bytestring\", \"ip6-dotint\", \"no-ip6-dotint\". See the resolv.conf(5) manual. Note that there is a distinction between an unset (default) list and an empty list. In nmcli, to unset the list set the value to \"\". To set an empty list, set it to \" \". Currently, an unset list has the same meaning as an empty list. That might change in the future. The \"trust-ad\" setting is only honored if the profile contributes name servers to resolv.conf, and if all contributing profiles have \"trust-ad\" enabled. When using a caching DNS plugin (dnsmasq or systemd-resolved in NetworkManager.conf) then \"edns0\" and \"trust-ad\" are automatically added. The valid \"ipv4.dns-options\" and \"ipv6.dns-options\" get merged together.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_PRIORITY N_("DNS servers priority. The relative priority for DNS servers specified by this setting. A lower numerical value is better (higher priority). Negative values have the special effect of excluding other configurations with a greater numerical priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. To avoid all DNS leaks, set the priority of the profile that should be used to the most negative value of all active connections profiles. Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. Note that commonly the resolver tries name servers in /etc/resolv.conf in the order listed, proceeding with the next server in the list on failure. See for example the \"rotate\" option of the dns-options setting. If there are any negative DNS priorities, then only name servers from the devices with that lowest priority will be considered. When using a DNS resolver that supports Conditional Forwarding or Split DNS (with dns=dnsmasq or dns=systemd-resolved settings), each connection is used to query domains in its search list. The search domains determine which name servers to ask, and the DNS priority is used to prioritize name servers based on the domain. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the best priority (lowest numerical value) wins. If a sub domain is configured on another interface it will be accepted regardless the priority, unless parent domain on the other interface has a negative priority, which causes the sub domain to be shadowed. With Split DNS one can avoid undesired DNS leaks by properly configuring DNS priorities and the search domains, so that only name servers of the desired interface are configured.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS_SEARCH N_("List of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names. When using a DNS plugin that supports Conditional Forwarding or Split DNS, then the search domains specify which name servers to query. This makes the behavior different from running with plain /etc/resolv.conf. For more information see also the dns-priority setting. When set on a profile that also enabled DHCP, the DNS search list received automatically (option 119 for DHCPv4 and option 24 for DHCPv6) gets merged with the manual list. This can be prevented by setting \"ignore-auto-dns\". Note that if no DNS searches are configured, the fallback will be derived from the domain from DHCP (option 15).") @@ -230,8 +248,11 @@ #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_REQUIRED_TIMEOUT N_("The minimum time interval in milliseconds for which dynamic IP configuration should be tried before the connection succeeds. This property is useful for example if both IPv4 and IPv6 are enabled and are allowed to fail. Normally the connection succeeds as soon as one of the two address families completes; by setting a required timeout for e.g. IPv4, one can ensure that even if IP6 succeeds earlier than IPv4, NetworkManager waits some time for IPv4 before the connection becomes active. Note that if \"may-fail\" is FALSE for the same address family, this property has no effect as NetworkManager needs to wait for the full DHCP timeout. A zero value means that no required timeout is present, -1 means the default value (either configuration ipvx.required-timeout override or zero).") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTE_METRIC N_("The default metric for routes that don't explicitly specify a metric. The default value -1 means that the metric is chosen automatically based on the device type. The metric applies to dynamic routes, manual (static) routes that don't have an explicit metric setting, address prefix routes, and the default route. Note that for IPv6, the kernel accepts zero (0) but coerces it to 1024 (user default). Hence, setting this property to zero effectively mean setting it to 1024. For IPv4, zero is a regular value for the metric.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTE_TABLE N_("Enable policy routing (source routing) and set the routing table used when adding routes. This affects all routes, including device-routes, IPv4LL, DHCP, SLAAC, default-routes and static routes. But note that static routes can individually overwrite the setting by explicitly specifying a non-zero routing table. If the table setting is left at zero, it is eligible to be overwritten via global configuration. If the property is zero even after applying the global configuration value, policy routing is disabled for the address family of this connection. Policy routing disabled means that NetworkManager will add all routes to the main table (except static routes that explicitly configure a different table). Additionally, NetworkManager will not delete any extraneous routes from tables except the main table. This is to preserve backward compatibility for users who manage routing tables outside of NetworkManager.") +#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTED_DNS N_("Whether to add routes for DNS servers. When enabled, NetworkManager adds a route for each DNS server that is associated with this connection either statically (defined in the connection profile) or dynamically (for example, retrieved via DHCP). The route guarantees that the DNS server is reached via this interface. When set to \"default\" (-1), the value from global configuration is used; if no global default is defined, this feature is disabled.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTES N_("Array of IP routes.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ROUTING_RULES N_("A comma separated list of routing rules for policy routing.") +#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_SHARED_DHCP_LEASE_TIME N_("This option allows you to specify a custom DHCP lease time for the shared connection method in seconds. The value should be either a number between 120 and 31536000 (one year) If this option is not specified, 3600 (one hour) is used. Special values are 0 for default value of 1 hour and 2147483647 (MAXINT32) for infinite lease time.") +#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_SHARED_DHCP_RANGE N_("This option allows you to specify a custom DHCP range for the shared connection method. The value is expected to be in `<START_ADDRESS>,<END_ADDRESS>` format. The range should be part of network set by ipv4.address option and it should not contain network address or broadcast address. If this option is not specified, the DHCP range will be automatically determined based on the interface address. The range will be selected to be adjacent to the interface address, either before or after it, with the larger possible range being preferred. The range will be adjusted to fill the available address space, except for networks with a prefix length greater than 24, which will be treated as if they have a prefix length of 24.") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_TEMP_PREFERRED_LIFETIME N_("The preferred lifetime of autogenerated temporary addresses, in seconds. Having a per-connection setting set to \"0\" (default) means fallback to global configuration \"ipv6.temp-preferred-lifetime\" setting\". If it's also unspecified or set to \"0\", fallback to read \"/proc/sys/net/ipv6/conf/default/temp_prefered_lft\".") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_TEMP_VALID_LIFETIME N_("The valid lifetime of autogenerated temporary addresses, in seconds. Having a per-connection setting set to \"0\" (default) means fallback to global configuration \"ipv6.temp-valid-lifetime\" setting\". If it's also unspecified or set to \"0\", fallback to read \"/proc/sys/net/ipv6/conf/default/temp_valid_lft\".") #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_TOKEN N_("Configure the token for draft-chown-6man-tokenised-ipv6-identifiers-02 IPv6 tokenized interface identifiers. Useful with eui64 addr-gen-mode. When set, the token is used as IPv6 interface identifier instead of the hardware address. This only applies to addresses from stateless autoconfiguration, not to IPv6 link local addresses.") @@ -249,6 +270,10 @@ #define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_REMOTE N_("The remote endpoint of the tunnel; the value must contain an IPv4 or IPv6 address.") #define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_TOS N_("The type of service (IPv4) or traffic class (IPv6) field to be set on tunneled packets.") #define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_TTL N_("The TTL to assign to tunneled packets. 0 is a special value meaning that packets inherit the TTL value.") +#define DESCRIBE_DOC_NM_SETTING_IPVLAN_MODE N_("The IPVLAN mode. Valid values: l2 (1), l3 (2), l3s (3)") +#define DESCRIBE_DOC_NM_SETTING_IPVLAN_PARENT N_("If given, specifies the parent interface name or parent connection UUID from which this IPVLAN interface should be created. If this property is not specified, the connection must contain an \"802-3-ethernet\" setting with a \"mac-address\" property.") +#define DESCRIBE_DOC_NM_SETTING_IPVLAN_PRIVATE N_("Whether the interface should be put in private mode.") +#define DESCRIBE_DOC_NM_SETTING_IPVLAN_VEPA N_("Whether the interface should be put in VEPA mode.") #define DESCRIBE_DOC_NM_SETTING_MACSEC_ENCRYPT N_("Whether the transmitted traffic must be encrypted.") #define DESCRIBE_DOC_NM_SETTING_MACSEC_MKA_CAK N_("The pre-shared CAK (Connectivity Association Key) for MACsec Key Agreement. Must be a string of 32 hexadecimal characters.") #define DESCRIBE_DOC_NM_SETTING_MACSEC_MKA_CAK_FLAGS N_("Flags indicating how to handle the \"mka-cak\" property.") diff --git a/src/meson.build b/src/meson.build index ceeee6a0..1a031982 100644 --- a/src/meson.build +++ b/src/meson.build @@ -120,6 +120,7 @@ if enable_tests subdir('libnm-client-test') subdir('libnm-glib-aux/tests') subdir('libnm-platform/tests') + subdir('libnm-core-aux-intern/tests') subdir('libnm-core-impl/tests') subdir('libnm-client-impl/tests') subdir('libnm-client-aux-extern/tests') diff --git a/src/nm-cloud-setup/main.c b/src/nm-cloud-setup/main.c index 084b5f62..44500ffa 100644 --- a/src/nm-cloud-setup/main.c +++ b/src/nm-cloud-setup/main.c @@ -11,6 +11,7 @@ #include "nmcs-provider-gcp.h" #include "nmcs-provider-azure.h" #include "nmcs-provider-aliyun.h" +#include "nmcs-provider-oci.h" #include "libnm-core-aux-intern/nm-libnm-core-utils.h" /*****************************************************************************/ @@ -104,6 +105,7 @@ _provider_detect(SigTermData *sigterm_data) NMCS_TYPE_PROVIDER_GCP, NMCS_TYPE_PROVIDER_AZURE, NMCS_TYPE_PROVIDER_ALIYUN, + NMCS_TYPE_PROVIDER_OCI, }; int i; gulong cancellable_signal_id; @@ -178,7 +180,7 @@ _map_interfaces_parse(void) nm_assert(j < alloc_len); m = &map_interfaces[j++]; - *m = (NMUtilsNamedValue){ + *m = (NMUtilsNamedValue) { .name = g_strndup(str, s - str), .value_str = hwaddr, }; @@ -187,7 +189,7 @@ _map_interfaces_parse(void) } nm_assert(j < alloc_len); - map_interfaces[j++] = (NMUtilsNamedValue){ + map_interfaces[j++] = (NMUtilsNamedValue) { .name = NULL, .value_str = NULL, }; @@ -196,13 +198,14 @@ _map_interfaces_parse(void) } static const char * -_device_get_hwaddr(NMDeviceEthernet *device) +_device_get_hwaddr(NMDevice *device) { static const NMUtilsNamedValue *gl_map_interfaces_map = NULL; static gsize gl_initialized = 0; const NMUtilsNamedValue *map = NULL; - nm_assert(NM_IS_DEVICE_ETHERNET(device)); + nm_assert(NM_IS_DEVICE_ETHERNET(device) || NM_IS_DEVICE_MACVLAN(device) + || NM_IS_DEVICE_VLAN(device)); /* Network interfaces in cloud environments are identified by their permanent * MAC address. @@ -236,11 +239,15 @@ _device_get_hwaddr(NMDeviceEthernet *device) return NULL; } - return nm_device_ethernet_get_permanent_hw_address(device); + if (NM_IS_DEVICE_ETHERNET(device)) { + return nm_device_ethernet_get_permanent_hw_address(NM_DEVICE_ETHERNET(device)); + } else { + return nm_device_get_hw_address(device); + } } static char ** -_nmc_get_hwaddrs(NMClient *nmc) +_nmc_get_ethernet_hwaddrs(NMClient *nmc) { gs_unref_ptrarray GPtrArray *hwaddrs = NULL; const GPtrArray *devices; @@ -261,7 +268,7 @@ _nmc_get_hwaddrs(NMClient *nmc) if (nm_device_get_state(device) < NM_DEVICE_STATE_UNAVAILABLE) continue; - hwaddr = _device_get_hwaddr(NM_DEVICE_ETHERNET(device)); + hwaddr = _device_get_hwaddr(device); if (!hwaddr) continue; @@ -303,7 +310,7 @@ _nmc_get_device_by_hwaddr(NMClient *nmc, const char *hwaddr) if (!NM_IS_DEVICE_ETHERNET(device)) continue; - hwaddr_dev = _device_get_hwaddr(NM_DEVICE_ETHERNET(device)); + hwaddr_dev = _device_get_hwaddr(device); if (!hwaddr_dev) continue; @@ -350,7 +357,7 @@ _get_config(GCancellable *sigterm_cancellable, NMCSProvider *provider, NMClient }; gs_strfreev char **hwaddrs = NULL; - hwaddrs = _nmc_get_hwaddrs(nmc); + hwaddrs = _nmc_get_ethernet_hwaddrs(nmc); nmcs_provider_get_config(provider, TRUE, @@ -387,11 +394,10 @@ _nmc_skip_connection_by_user_data(NMConnection *connection) } static gboolean -_nmc_skip_connection_by_type(NMConnection *connection) +_nmc_skip_connection_by_type(NMConnection *connection, const char *connection_type) { - if (!nm_streq0(nm_connection_get_connection_type(connection), NM_SETTING_WIRED_SETTING_NAME)) + if (!nm_streq0(nm_connection_get_connection_type(connection), connection_type)) return TRUE; - if (!nm_connection_get_setting_ip4_config(connection)) return TRUE; @@ -632,7 +638,7 @@ try_again: return any_changes; } - if (_nmc_skip_connection_by_type(applied_connection)) { + if (_nmc_skip_connection_by_type(applied_connection, NM_SETTING_WIRED_SETTING_NAME)) { _LOGD("config device %s: device has no suitable applied connection. Skip", hwaddr); return any_changes; } @@ -766,7 +772,7 @@ main(int argc, const char *const *argv) sigterm_cancellable = g_cancellable_new(); - sigterm_data = (SigTermData){ + sigterm_data = (SigTermData) { .cancellable = sigterm_cancellable, .enabled = TRUE, .signal_received = FALSE, diff --git a/src/nm-cloud-setup/meson.build b/src/nm-cloud-setup/meson.build index b1269ec6..adb425ec 100644 --- a/src/nm-cloud-setup/meson.build +++ b/src/nm-cloud-setup/meson.build @@ -9,6 +9,12 @@ if install_systemdunitdir configuration: data_conf, ) + test( + 'check-nm-cloud-setup.service', + find_program(join_paths(source_root, 'src/tests/check-systemd-unit.sh')), + args: [ join_paths(meson.current_build_dir(), 'nm-cloud-setup.service') ], + ) + install_data( 'nm-cloud-setup.timer', install_dir: systemd_systemdsystemunitdir, @@ -30,12 +36,14 @@ libnm_cloud_setup_core = static_library( 'nmcs-provider-gcp.c', 'nmcs-provider-azure.c', 'nmcs-provider-aliyun.c', + 'nmcs-provider-oci.c', 'nmcs-provider.c', ), dependencies: [ libnm_dep, glib_dep, libcurl_dep, + jansson_dep, ], ) diff --git a/src/nm-cloud-setup/nm-cloud-setup-utils.c b/src/nm-cloud-setup/nm-cloud-setup-utils.c index 75739c7c..314e4011 100644 --- a/src/nm-cloud-setup/nm-cloud-setup-utils.c +++ b/src/nm-cloud-setup/nm-cloud-setup-utils.c @@ -126,7 +126,7 @@ nmcs_wait_for_objects_iterate_until_done(GMainContext *context, int timeout_msec _wait_for_objects_iterate_loops = g_slist_prepend(_wait_for_objects_iterate_loops, loop); G_UNLOCK(_wait_for_objects_lock); - data = (WaitForObjectsData){ + data = (WaitForObjectsData) { .loop = loop, .got_timeout = FALSE, }; @@ -615,3 +615,46 @@ again: NM_SET_OUT(out_version_id_changed, FALSE); return TRUE; } + +/*****************************************************************************/ + +typedef struct { + GMainLoop *main_loop; + GError **error; + NMActiveConnection *active_connection; +} AddAndActivateData; + +static void +_nmcs_add_and_activate_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + AddAndActivateData *data = user_data; + + data->active_connection = + nm_client_add_and_activate_connection_finish(NM_CLIENT(source), result, data->error); + g_main_loop_quit(data->main_loop); +} + +NMActiveConnection * +nmcs_add_and_activate(NMClient *client, + GCancellable *sigterm_cancellable, + NMConnection *connection, + GError **error) +{ + nm_auto_unref_gmainloop GMainLoop *main_loop = g_main_loop_new(NULL, FALSE); + AddAndActivateData data = { + .main_loop = main_loop, + .error = error, + }; + + nm_client_add_and_activate_connection_async(client, + connection, + NULL, + NULL, + sigterm_cancellable, + _nmcs_add_and_activate_cb, + &data); + + g_main_loop_run(main_loop); + + return data.active_connection; +} diff --git a/src/nm-cloud-setup/nm-cloud-setup-utils.h b/src/nm-cloud-setup/nm-cloud-setup-utils.h index 4ca4634c..96205369 100644 --- a/src/nm-cloud-setup/nm-cloud-setup-utils.h +++ b/src/nm-cloud-setup/nm-cloud-setup-utils.h @@ -12,6 +12,7 @@ #define NMCS_ENV_NM_CLOUD_SETUP_AZURE "NM_CLOUD_SETUP_AZURE" #define NMCS_ENV_NM_CLOUD_SETUP_EC2 "NM_CLOUD_SETUP_EC2" #define NMCS_ENV_NM_CLOUD_SETUP_GCP "NM_CLOUD_SETUP_GCP" +#define NMCS_ENV_NM_CLOUD_SETUP_OCI "NM_CLOUD_SETUP_OCI" #define NMCS_ENV_NM_CLOUD_SETUP_LOG "NM_CLOUD_SETUP_LOG" /* Undocumented/internal environment variables for configuring nm-cloud-setup. @@ -20,6 +21,7 @@ #define NMCS_ENV_NM_CLOUD_SETUP_AZURE_HOST "NM_CLOUD_SETUP_AZURE_HOST" #define NMCS_ENV_NM_CLOUD_SETUP_EC2_HOST "NM_CLOUD_SETUP_EC2_HOST" #define NMCS_ENV_NM_CLOUD_SETUP_GCP_HOST "NM_CLOUD_SETUP_GCP_HOST" +#define NMCS_ENV_NM_CLOUD_SETUP_OCI_HOST "NM_CLOUD_SETUP_OCI_HOST" #define NMCS_ENV_NM_CLOUD_SETUP_MAP_INTERFACES "NM_CLOUD_SETUP_MAP_INTERFACES" /*****************************************************************************/ @@ -126,7 +128,7 @@ again: char *nmcs_utils_uri_build_concat_v(const char *base, const char **components, gsize n_components); #define nmcs_utils_uri_build_concat(base, ...) \ - nmcs_utils_uri_build_concat_v(base, ((const char *[]){__VA_ARGS__}), NM_NARG(__VA_ARGS__)) + nmcs_utils_uri_build_concat_v(base, ((const char *[]) {__VA_ARGS__}), NM_NARG(__VA_ARGS__)) const char *nmcs_utils_uri_complete_interned(const char *uri); @@ -151,6 +153,11 @@ NMConnection *nmcs_device_get_applied_connection(NMDevice *device, guint64 *version_id, GError **error); +NMActiveConnection *nmcs_add_and_activate(NMClient *client, + GCancellable *sigterm_cancellable, + NMConnection *connection, + GError **error); + gboolean nmcs_device_reapply(NMDevice *device, GCancellable *sigterm_cancellable, NMConnection *connection, diff --git a/src/nm-cloud-setup/nm-cloud-setup.service.in b/src/nm-cloud-setup/nm-cloud-setup.service.in index cb782b22..455f0ee0 100644 --- a/src/nm-cloud-setup/nm-cloud-setup.service.in +++ b/src/nm-cloud-setup/nm-cloud-setup.service.in @@ -31,6 +31,7 @@ ExecStart=@libexecdir@/nm-cloud-setup #Environment=NM_CLOUD_SETUP_GCP=yes #Environment=NM_CLOUD_SETUP_AZURE=yes #Environment=NM_CLOUD_SETUP_ALIYUN=yes +#Environment=NM_CLOUD_SETUP_OCI=yes CapabilityBoundingSet= KeyringMode=private diff --git a/src/nm-cloud-setup/nm-http-client.c b/src/nm-cloud-setup/nm-http-client.c index 20ef6473..0731ba25 100644 --- a/src/nm-cloud-setup/nm-http-client.c +++ b/src/nm-cloud-setup/nm-http-client.c @@ -201,7 +201,7 @@ _ehandle_complete(EHandleData *edata, GError *error_take) _ehandle_free_ehandle(edata); req_result = g_slice_new(GetResult); - *req_result = (GetResult){ + *req_result = (GetResult) { .response_code = response_code, /* This ensures that response_data is always NUL terminated. This is an important guarantee * that NMHttpClient makes. */ @@ -280,7 +280,7 @@ nm_http_client_req(NMHttpClient *self, priv = NM_HTTP_CLIENT_GET_PRIVATE(self); edata = g_slice_new(EHandleData); - *edata = (EHandleData){ + *edata = (EHandleData) { .task = nm_g_task_new(self, cancellable, nm_http_client_req, callback, user_data), .recv_data = NM_STR_BUF_INIT(0, FALSE), .max_data = max_data, @@ -558,7 +558,7 @@ nm_http_client_poll_req(NMHttpClient *self, g_return_if_fail(!cancellable || G_CANCELLABLE(cancellable)); poll_req_data = g_slice_new(PollReqData); - *poll_req_data = (PollReqData){ + *poll_req_data = (PollReqData) { .task = nm_g_task_new(self, cancellable, nm_http_client_poll_req, callback, user_data), .uri = g_strdup(uri), .request_timeout_ms = request_timeout_ms, diff --git a/src/nm-cloud-setup/nmcs-provider-azure.c b/src/nm-cloud-setup/nmcs-provider-azure.c index 78eda16c..d4999b5f 100644 --- a/src/nm-cloud-setup/nmcs-provider-azure.c +++ b/src/nm-cloud-setup/nmcs-provider-azure.c @@ -500,7 +500,7 @@ _get_net_ifaces_list_cb(GObject *source, GAsyncResult *result, gpointer user_dat continue; iface_data = g_slice_new(AzureIfaceData); - *iface_data = (AzureIfaceData){ + *iface_data = (AzureIfaceData) { .get_config_data = get_config_data, .iface_get_config = NULL, .intern_iface_idx = intern_iface_idx, diff --git a/src/nm-cloud-setup/nmcs-provider-gcp.c b/src/nm-cloud-setup/nmcs-provider-gcp.c index 4d9ef965..ce932c1d 100644 --- a/src/nm-cloud-setup/nmcs-provider-gcp.c +++ b/src/nm-cloud-setup/nmcs-provider-gcp.c @@ -381,7 +381,7 @@ _get_net_ifaces_list_cb(GObject *source, GAsyncResult *result, gpointer user_dat continue; iface_data = g_slice_new(GCPIfaceData); - *iface_data = (GCPIfaceData){ + *iface_data = (GCPIfaceData) { .get_config_data = get_config_data, .iface_get_config = NULL, .intern_iface_idx = intern_iface_idx, diff --git a/src/nm-cloud-setup/nmcs-provider-oci.c b/src/nm-cloud-setup/nmcs-provider-oci.c new file mode 100644 index 00000000..b0b0edf9 --- /dev/null +++ b/src/nm-cloud-setup/nmcs-provider-oci.c @@ -0,0 +1,221 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "libnm-client-aux-extern/nm-default-client.h" +#include "nmcs-provider-oci.h" +#include "nm-cloud-setup-utils.h" +#include "libnm-glib-aux/nm-jansson.h" + +/*****************************************************************************/ + +#define HTTP_TIMEOUT_MS 3000 + +#define NM_OCI_HEADER "Authorization:Bearer Oracle" +#define NM_OCI_HOST "169.254.169.254" +#define NM_OCI_BASE "http://" NM_OCI_HOST + +NMCS_DEFINE_HOST_BASE(_oci_base, NMCS_ENV_NM_CLOUD_SETUP_OCI_HOST, NM_OCI_BASE); + +#define _oci_uri_concat(...) nmcs_utils_uri_build_concat(_oci_base(), "opc/v2/", __VA_ARGS__) + +/*****************************************************************************/ + +struct _NMCSProviderOCI { + NMCSProvider parent; +}; + +struct _NMCSProviderOCIClass { + NMCSProviderClass parent; +}; + +G_DEFINE_TYPE(NMCSProviderOCI, nmcs_provider_oci, NMCS_TYPE_PROVIDER); + +/*****************************************************************************/ + +static void +_detect_done_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + gs_unref_object GTask *task = user_data; + gs_free_error GError *get_error = NULL; + gs_free_error GError *error = NULL; + + nm_http_client_poll_req_finish(NM_HTTP_CLIENT(source), result, NULL, NULL, &get_error); + + if (nm_utils_error_is_cancelled(get_error)) { + g_task_return_error(task, g_steal_pointer(&get_error)); + return; + } + + if (get_error) { + nm_utils_error_set(&error, + NM_UTILS_ERROR_UNKNOWN, + "failure to get OCI instance data: %s", + get_error->message); + g_task_return_error(task, g_steal_pointer(&error)); + return; + } + + g_task_return_boolean(task, TRUE); +} + +static void +detect(NMCSProvider *provider, GTask *task) +{ + NMHttpClient *http_client; + gs_free char *uri = NULL; + + http_client = nmcs_provider_get_http_client(provider); + + nm_http_client_poll_req(http_client, + (uri = _oci_uri_concat("instance")), + HTTP_TIMEOUT_MS, + 256 * 1024, + 7000, + 1000, + NM_MAKE_STRV(NM_OCI_HEADER), + NULL, + g_task_get_cancellable(task), + NULL, + NULL, + _detect_done_cb, + task); +} + +/*****************************************************************************/ + +#define _VNIC_WARN(msg) _LOGW("get-config: " msg "(VNIC %s idx=%zu)", vnic_id, i) + +static void +_get_config_done_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + NMCSProviderGetConfigTaskData *get_config_data; + NMCSProviderGetConfigIfaceData *config_iface_data; + gs_unref_bytes GBytes *response = NULL; + gs_free_error GError *error = NULL; + nm_auto_decref_json json_t *vnics = NULL; + size_t i; + + nm_http_client_poll_req_finish(NM_HTTP_CLIENT(source), result, NULL, &response, &error); + + if (nm_utils_error_is_cancelled(error)) + return; + + get_config_data = user_data; + + if (error) + goto out; + + vnics = json_loads(g_bytes_get_data(response, NULL), JSON_REJECT_DUPLICATES, NULL); + if (!vnics || !json_is_array(vnics)) { + nm_utils_error_set(&error, + NM_UTILS_ERROR_UNKNOWN, + "get-config: JSON parse failure, can't configure VNICs"); + goto out; + } + + for (i = 0; i < json_array_size(vnics); i++) { + json_t *vnic, *field; + const char *vnic_id = "", *val; + gs_free char *mac = NULL; + in_addr_t addr; + int prefix; + + vnic = json_array_get(vnics, i); + if (!json_is_object(vnic)) { + _VNIC_WARN("JSON parse failure, ignoring VNIC"); + continue; + } + + field = json_object_get(vnic, "vnicId"); + vnic_id = field && json_is_string(field) ? json_string_value(field) : ""; + + field = json_object_get(vnic, "macAddr"); + val = field && json_is_string(field) ? json_string_value(field) : NULL; + if (!val) { + _VNIC_WARN("missing or invalid 'macAddr', ignoring VNIC"); + continue; + } + + mac = nmcs_utils_hwaddr_normalize(val, json_string_length(field)); + config_iface_data = nmcs_provider_get_config_iface_data_create(get_config_data, FALSE, mac); + config_iface_data->iface_idx = i; + + field = json_object_get(vnic, "privateIp"); + val = field && json_is_string(field) ? json_string_value(field) : NULL; + if (val && nm_inet_parse_bin(AF_INET, val, NULL, &addr)) { + config_iface_data->has_ipv4s = TRUE; + config_iface_data->ipv4s_len = 1; + config_iface_data->ipv4s_arr = g_new(in_addr_t, 1); + config_iface_data->ipv4s_arr[0] = addr; + } else { + _VNIC_WARN("missing or invalid 'privateIp'"); + } + + field = json_object_get(vnic, "virtualRouterIp"); + val = field && json_is_string(field) ? json_string_value(field) : NULL; + if (val && nm_inet_parse_bin(AF_INET, val, NULL, &addr)) { + config_iface_data->has_gateway = TRUE; + config_iface_data->gateway = addr; + } else { + _VNIC_WARN("missing or invalid 'virtualRouterIp'"); + } + + field = json_object_get(vnic, "subnetCidrBlock"); + val = field && json_is_string(field) ? json_string_value(field) : NULL; + if (val && nm_inet_parse_with_prefix_bin(AF_INET, val, NULL, &addr, &prefix)) { + config_iface_data->has_cidr = TRUE; + config_iface_data->cidr_addr = addr; + config_iface_data->cidr_prefix = prefix; + } else { + _VNIC_WARN("missing or invalid 'subnetCidrBlock'"); + } + } + +out: + _nmcs_provider_get_config_task_maybe_return(get_config_data, g_steal_pointer(&error)); +} + +static void +get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_data) +{ + gs_free const char *uri = NULL; + + nm_http_client_poll_req(nmcs_provider_get_http_client(provider), + (uri = _oci_uri_concat("vnics")), + HTTP_TIMEOUT_MS, + 256 * 1024, + 15000, + 1000, + NM_MAKE_STRV(NM_OCI_HEADER), + NULL, + get_config_data->intern_cancellable, + NULL, + NULL, + _get_config_done_cb, + get_config_data); +} + +/*****************************************************************************/ + +static void +nmcs_provider_oci_init(NMCSProviderOCI *self) +{} + +static void +dispose(GObject *object) +{ + G_OBJECT_CLASS(nmcs_provider_oci_parent_class)->dispose(object); +} + +static void +nmcs_provider_oci_class_init(NMCSProviderOCIClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + NMCSProviderClass *provider_class = NMCS_PROVIDER_CLASS(klass); + + object_class->dispose = dispose; + + provider_class->_name = "oci"; + provider_class->_env_provider_enabled = NMCS_ENV_NM_CLOUD_SETUP_OCI; + provider_class->detect = detect; + provider_class->get_config = get_config; +} diff --git a/src/nm-cloud-setup/nmcs-provider-oci.h b/src/nm-cloud-setup/nmcs-provider-oci.h new file mode 100644 index 00000000..8447bc1c --- /dev/null +++ b/src/nm-cloud-setup/nmcs-provider-oci.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef __NMCS_PROVIDER_OCI_H__ +#define __NMCS_PROVIDER_OCI_H__ + +#include "nmcs-provider.h" + +/*****************************************************************************/ + +typedef struct _NMCSProviderOCI NMCSProviderOCI; +typedef struct _NMCSProviderOCIClass NMCSProviderOCIClass; + +#define NMCS_TYPE_PROVIDER_OCI (nmcs_provider_oci_get_type()) +#define NMCS_PROVIDER_OCI(obj) \ + (_NM_G_TYPE_CHECK_INSTANCE_CAST((obj), NMCS_TYPE_PROVIDER_OCI, NMCSProviderOCI)) +#define NMCS_PROVIDER_OCI_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), NMCS_TYPE_PROVIDER_OCI, NMCSProviderOCIClass)) +#define NMCS_IS_PROVIDER_OCI(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NMCS_TYPE_PROVIDER_OCI)) +#define NMCS_IS_PROVIDER_OCI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NMCS_TYPE_PROVIDER_OCI)) +#define NMCS_PROVIDER_OCI_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NMCS_TYPE_PROVIDER_OCI, NMCSProviderOCIClass)) + +GType nmcs_provider_oci_get_type(void); + +/*****************************************************************************/ + +#endif /* __NMCS_PROVIDER_OCI_H__ */ diff --git a/src/nm-cloud-setup/nmcs-provider.c b/src/nm-cloud-setup/nmcs-provider.c index 5b4412b3..0f06c4e2 100644 --- a/src/nm-cloud-setup/nmcs-provider.c +++ b/src/nm-cloud-setup/nmcs-provider.c @@ -3,6 +3,8 @@ #include "libnm-client-aux-extern/nm-default-client.h" #include "nmcs-provider.h" +#include "nmcs-provider-aliyun.h" +#include "nmcs-provider-oci.h" #include "nm-cloud-setup-utils.h" @@ -95,7 +97,7 @@ nmcs_provider_get_config_result_new(GHashTable *iface_datas) g_ptr_array_add(ptrarr, NULL); result = g_new(NMCSProviderGetConfigResult, 1); - *result = (NMCSProviderGetConfigResult){ + *result = (NMCSProviderGetConfigResult) { .iface_datas = g_hash_table_ref(iface_datas), .n_iface_datas = n_iface_datas, .iface_datas_arr = @@ -185,7 +187,7 @@ nmcs_provider_get_config_iface_data_create(NMCSProviderGetConfigTaskData *get_co nm_assert(NMCS_IS_PROVIDER(get_config_data->self)); iface_data = g_slice_new(NMCSProviderGetConfigIfaceData); - *iface_data = (NMCSProviderGetConfigIfaceData){ + *iface_data = (NMCSProviderGetConfigIfaceData) { .get_config_data = get_config_data, .hwaddr = g_strdup(hwaddr), .iface_idx = -1, @@ -198,7 +200,7 @@ nmcs_provider_get_config_iface_data_create(NMCSProviderGetConfigTaskData *get_co * Also, knowing the type would allow us to initialize to something other than * false/0/NULL/0.0. */ if (G_OBJECT_TYPE(get_config_data->self) == nmcs_provider_aliyun_get_type()) { - iface_data->priv.aliyun = (typeof(iface_data->priv.aliyun)){ + iface_data->priv.aliyun = (typeof(iface_data->priv.aliyun)) { .has_primary_ip_address = FALSE, }; } @@ -293,7 +295,7 @@ nmcs_provider_get_config(NMCSProvider *self, _LOGD("get-config: starting"); get_config_data = g_slice_new(NMCSProviderGetConfigTaskData); - *get_config_data = (NMCSProviderGetConfigTaskData){ + *get_config_data = (NMCSProviderGetConfigTaskData) { /* "self" is kept alive by "task". */ .self = self, .task = nm_g_task_new(self, cancellable, nmcs_provider_get_config, callback, user_data), diff --git a/src/nm-cloud-setup/nmcs-provider.h b/src/nm-cloud-setup/nmcs-provider.h index 9e5eeebe..98e50ea3 100644 --- a/src/nm-cloud-setup/nmcs-provider.h +++ b/src/nm-cloud-setup/nmcs-provider.h @@ -220,11 +220,4 @@ void nmcs_provider_get_config(NMCSProvider *provider, NMCSProviderGetConfigResult * nmcs_provider_get_config_finish(NMCSProvider *provider, GAsyncResult *result, GError **error); -/*****************************************************************************/ - -/* Forward declare the implemented gtype getters so we can use it at a few places without requiring - * to include the full header. The other parts of those headers should not be used aside where they - * are necessary. */ -GType nmcs_provider_aliyun_get_type(void); - #endif /* __NMCS_PROVIDER_H__ */ diff --git a/src/nm-dispatcher/nm-dispatcher-utils.c b/src/nm-dispatcher/nm-dispatcher-utils.c index 6659936f..030506e9 100644 --- a/src/nm-dispatcher/nm-dispatcher-utils.c +++ b/src/nm-dispatcher/nm-dispatcher-utils.c @@ -264,22 +264,43 @@ construct_ip_items(GPtrArray *items, int addr_family, GVariant *ip_config, const g_variant_unref(val); } - val = g_variant_lookup_value(ip_config, - "nameservers", - addr_family == AF_INET ? G_VARIANT_TYPE("au") - : G_VARIANT_TYPE("aay")); + /* For name servers, prefer the new key and fall back to the old one. */ + val = g_variant_lookup_value(ip_config, "nameservers-full", G_VARIANT_TYPE("as")); if (val) { - gs_strfreev char **v = NULL; + nm_auto_unref_ptrarray GPtrArray *arr = NULL; + GVariantIter iter; + const char *str; + + arr = g_ptr_array_new_full(g_variant_n_children(val) + 1, NULL); + g_variant_iter_init(&iter, val); + while (g_variant_iter_next(&iter, "&s", &str)) { + g_ptr_array_add(arr, (gpointer) str); + } + g_ptr_array_add(arr, NULL); - if (addr_family == AF_INET) - v = nm_utils_ip4_dns_from_variant(val); - else - v = nm_utils_ip6_dns_from_variant(val); _items_add_strv(items, prefix, addr_family == AF_INET ? "IP4_NAMESERVERS" : "IP6_NAMESERVERS", - NM_CAST_STRV_CC(v)); + (const char *const *) arr->pdata); g_variant_unref(val); + } else { + val = g_variant_lookup_value(ip_config, + "nameservers", + addr_family == AF_INET ? G_VARIANT_TYPE("au") + : G_VARIANT_TYPE("aay")); + if (val) { + gs_strfreev char **v = NULL; + + if (addr_family == AF_INET) + v = nm_utils_ip4_dns_from_variant(val); + else + v = nm_utils_ip6_dns_from_variant(val); + _items_add_strv(items, + prefix, + addr_family == AF_INET ? "IP4_NAMESERVERS" : "IP6_NAMESERVERS", + NM_CAST_STRV_CC(v)); + g_variant_unref(val); + } } val = g_variant_lookup_value(ip_config, "domains", G_VARIANT_TYPE_STRING_ARRAY); diff --git a/src/nm-initrd-generator/nm-initrd-generator.c b/src/nm-initrd-generator/nm-initrd-generator.c index d84e95e5..b89b4e41 100644 --- a/src/nm-initrd-generator/nm-initrd-generator.c +++ b/src/nm-initrd-generator/nm-initrd-generator.c @@ -11,6 +11,7 @@ #include "libnm-core-intern/nm-core-internal.h" #include "libnm-core-intern/nm-keyfile-internal.h" #include "libnm-glib-aux/nm-io-utils.h" +#include "libnm-glib-aux/nm-keyfile-aux.h" #include "libnm-log-core/nm-logging.h" /*****************************************************************************/ @@ -154,6 +155,9 @@ main(int argc, char *argv[]) gint64 carrier_timeout_sec = 0; gs_unref_array GArray *confs = NULL; guint i; + gs_strfreev char **global_dns_servers = NULL; + gs_free char *dns_backend = NULL; + gs_free char *dns_resolve_mode = NULL; option_context = g_option_context_new( "-- [ip=...] [rd.route=...] [bridge=...] [bond=...] [team=...] [vlan=...] " @@ -193,7 +197,10 @@ main(int argc, char *argv[]) sysfs_dir, (const char *const *) remaining, &hostname, - &carrier_timeout_sec); + &carrier_timeout_sec, + &global_dns_servers, + &dns_backend, + &dns_resolve_mode); confs = g_array_new(FALSE, FALSE, sizeof(NMUtilsNamedValue)); g_array_set_clear_func(confs, (GDestroyNotify) nm_utils_named_value_clear_with_g_free); @@ -226,13 +233,68 @@ main(int argc, char *argv[]) : "from \"rd.net.timeout.carrier\""); } - v = (NMUtilsNamedValue){ + v = (NMUtilsNamedValue) { .name = g_strdup_printf("%s/15-carrier-timeout.conf", run_config_dir), .value_str = g_key_file_to_data(keyfile, NULL, NULL), }; g_array_append_val(confs, v); } + if (global_dns_servers || dns_resolve_mode) { + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + NMUtilsNamedValue v; + gs_free char *dns_list = NULL; + + keyfile = g_key_file_new(); + g_key_file_set_list_separator(keyfile, NM_CONFIG_KEYFILE_LIST_SEPARATOR); + nm_key_file_add_group(keyfile, NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS); + + if (dns_resolve_mode) { + g_key_file_set_value(keyfile, + NM_CONFIG_KEYFILE_GROUP_GLOBAL_DNS, + NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_RESOLVE_MODE, + dns_resolve_mode); + } + + if (global_dns_servers) { + dns_list = g_strjoinv(",", global_dns_servers); + g_key_file_set_value(keyfile, + NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN "*", + NM_CONFIG_KEYFILE_KEY_GLOBAL_DNS_DOMAIN_SERVERS, + dns_list); + } + + if (!dump_to_stdout) { + add_keyfile_comment(keyfile, "from \"rd.net.dns\" and \"rd.net.dns-resolv-mode\""); + } + + v = (NMUtilsNamedValue) { + .name = g_strdup_printf("%s/16-global-dns.conf", run_config_dir), + .value_str = g_key_file_to_data(keyfile, NULL, NULL), + }; + g_array_append_val(confs, v); + } + + if (dns_backend) { + nm_auto_unref_keyfile GKeyFile *keyfile = NULL; + NMUtilsNamedValue v; + + keyfile = g_key_file_new(); + g_key_file_set_value(keyfile, + NM_CONFIG_KEYFILE_GROUP_MAIN, + NM_CONFIG_KEYFILE_KEY_MAIN_DNS, + dns_backend); + if (!dump_to_stdout) { + add_keyfile_comment(keyfile, "from \"rd.net.dns-backend\""); + } + + v = (NMUtilsNamedValue) { + .name = g_strdup_printf("%s/16-dns-backend.conf", run_config_dir), + .value_str = g_key_file_to_data(keyfile, NULL, NULL), + }; + g_array_append_val(confs, v); + } + if (dump_to_stdout) { nm_clear_g_free(&connections_dir); nm_clear_g_free(&initrd_dir); diff --git a/src/nm-initrd-generator/nm-initrd-generator.h b/src/nm-initrd-generator/nm-initrd-generator.h index 87db9fc6..c2baad4e 100644 --- a/src/nm-initrd-generator/nm-initrd-generator.h +++ b/src/nm-initrd-generator/nm-initrd-generator.h @@ -45,6 +45,9 @@ GHashTable *nmi_cmdline_reader_parse(const char *etc_connections_dir, const char *sysfs_dir, const char *const *argv, char **hostname, - gint64 *carrier_timeout_sec); + gint64 *carrier_timeout_sec, + char ***global_dns_servers, + char **dns_backend, + char **dns_resolve_mode); #endif /* __NM_INITRD_GENERATOR_H__ */ diff --git a/src/nm-initrd-generator/nmi-cmdline-reader.c b/src/nm-initrd-generator/nmi-cmdline-reader.c index 3703ff0c..d6dc1fcb 100644 --- a/src/nm-initrd-generator/nmi-cmdline-reader.c +++ b/src/nm-initrd-generator/nmi-cmdline-reader.c @@ -34,6 +34,9 @@ typedef struct { NMConnection *default_connection; /* connection not bound to any ifname */ char *hostname; GHashTable *znet_ifnames; + GPtrArray *global_dns; + char *dns_backend; + char *dns_resolve_mode; /* Parameters to be set for all connections */ gboolean ignore_auto_dns; @@ -50,7 +53,7 @@ reader_new(void) Reader *reader; reader = g_slice_new(Reader); - *reader = (Reader){ + *reader = (Reader) { .hash = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_object_unref), .explicit_ip_connections = g_hash_table_new_full(nm_direct_hash, NULL, g_object_unref, NULL), @@ -69,12 +72,15 @@ reader_destroy(Reader *reader, gboolean free_hash) g_ptr_array_unref(reader->array); g_ptr_array_unref(reader->vlan_parents); + nm_clear_pointer(&reader->global_dns, g_ptr_array_unref); g_hash_table_unref(reader->explicit_ip_connections); hash = g_steal_pointer(&reader->hash); nm_clear_g_free(&reader->hostname); g_hash_table_unref(reader->znet_ifnames); nm_clear_g_free(&reader->dhcp4_vci); nm_clear_g_free(&reader->dhcp_dscp); + nm_clear_g_free(&reader->dns_backend); + nm_clear_g_free(&reader->dns_resolve_mode); nm_g_slice_free(reader); if (!free_hash) return g_steal_pointer(&hash); @@ -1220,6 +1226,43 @@ reader_parse_rd_znet(Reader *reader, char *argument, gboolean net_ifnames) } static void +reader_parse_global_dns(Reader *reader, char *argument) +{ + if (!nm_dns_uri_parse(AF_UNSPEC, argument, NULL)) { + _LOGW(LOGD_CORE, "rd.net.dns: invalid server '%s'", argument); + return; + } + + if (!reader->global_dns) { + reader->global_dns = g_ptr_array_new_with_free_func(g_free); + } + + g_ptr_array_add(reader->global_dns, g_strdup(argument)); +} + +static void +reader_parse_dns_backend(Reader *reader, const char *argument) +{ + if (!NM_IN_STRSET(argument, "none", "default", "systemd-resolved", "dnsmasq", "dnsconfd")) { + _LOGW(LOGD_CORE, "rd.net.dns-backend: invalid value '%s'", argument); + return; + } + + reader->dns_backend = g_strdup(argument); +} + +static void +reader_parse_dns_resolve_mode(Reader *reader, const char *argument) +{ + if (!NM_IN_STRSET(argument, "backup", "prefer", "exclusive")) { + _LOGW(LOGD_CORE, "rd.net.dns-resolve-mode: invalid value '%s'", argument); + return; + } + + reader->dns_resolve_mode = g_strdup(argument); +} + +static void reader_parse_ethtool(Reader *reader, char *argument) { NMConnection *connection; @@ -1392,7 +1435,10 @@ nmi_cmdline_reader_parse(const char *etc_connections_dir, const char *sysfs_dir, const char *const *argv, char **hostname, - gint64 *carrier_timeout_sec) + gint64 *carrier_timeout_sec, + char ***global_dns_servers, + char **dns_backend, + char **dns_resolve_mode) { Reader *reader; const char *tag; @@ -1509,6 +1555,12 @@ nmi_cmdline_reader_parse(const char *etc_connections_dir, bootif_val = g_strdup(argument); } else if (nm_streq(tag, "rd.ethtool")) { reader_parse_ethtool(reader, argument); + } else if (nm_streq(tag, "rd.net.dns")) { + reader_parse_global_dns(reader, argument); + } else if (nm_streq(tag, "rd.net.dns-backend")) { + reader_parse_dns_backend(reader, argument); + } else if (nm_streq(tag, "rd.net.dns-resolve-mode")) { + reader_parse_dns_resolve_mode(reader, argument); } } @@ -1623,8 +1675,19 @@ nmi_cmdline_reader_parse(const char *etc_connections_dir, g_hash_table_foreach(reader->hash, _normalize_conn, NULL); NM_SET_OUT(hostname, g_steal_pointer(&reader->hostname)); - NM_SET_OUT(carrier_timeout_sec, reader->carrier_timeout_sec); + NM_SET_OUT(dns_backend, g_steal_pointer(&reader->dns_backend)); + NM_SET_OUT(dns_resolve_mode, g_steal_pointer(&reader->dns_resolve_mode)); + + if (reader->global_dns) { + if (global_dns_servers) { + g_ptr_array_add(reader->global_dns, NULL); + *global_dns_servers = (char **) g_ptr_array_free(reader->global_dns, FALSE); + reader->global_dns = NULL; + } + } else { + NM_SET_OUT(global_dns_servers, NULL); + } return reader_destroy(reader, FALSE); } diff --git a/src/nm-initrd-generator/tests/test-cmdline-reader.c b/src/nm-initrd-generator/tests/test-cmdline-reader.c index 33b83497..a0100764 100644 --- a/src/nm-initrd-generator/tests/test-cmdline-reader.c +++ b/src/nm-initrd-generator/tests/test-cmdline-reader.c @@ -23,7 +23,12 @@ /*****************************************************************************/ -#define _parse(ARGV, out_hostname, out_carrier_timeout_sec) \ +#define _parse(ARGV, \ + out_hostname, \ + out_carrier_timeout_sec, \ + _out_global_dns_servers, \ + _out_dns_backend, \ + _out_dns_resolve_mode) \ ({ \ const char *const *const _ARGV = (ARGV); \ char **const _out_hostname = (out_hostname); \ @@ -34,26 +39,31 @@ TEST_INITRD_DIR "/sysfs", \ _ARGV, \ _out_hostname, \ - _out_carrier_timeout_sec); \ - \ + _out_carrier_timeout_sec, \ + _out_global_dns_servers, \ + _out_dns_backend, \ + _out_dns_resolve_mode); \ g_assert(_connections); \ \ _connections; \ }) -#define _parse_cons(ARGV) \ - ({ \ - GHashTable *_con_connections; \ - gs_free char *_con_hostname = NULL; \ - gint64 _con_carrier_timeout_sec = 0; \ - \ - _con_connections = _parse((ARGV), \ - nmtst_get_rand_bool() ? &_con_hostname : NULL, \ - nmtst_get_rand_bool() ? &_con_carrier_timeout_sec : NULL); \ - g_assert_cmpstr(_con_hostname, ==, NULL); \ - g_assert_cmpint(_con_carrier_timeout_sec, ==, 0); \ - \ - _con_connections; \ +#define _parse_cons(ARGV) \ + ({ \ + GHashTable *_con_connections; \ + gs_free char *_con_hostname = NULL; \ + gint64 _con_carrier_timeout_sec = 0; \ + \ + _con_connections = _parse((ARGV), \ + nmtst_get_rand_bool() ? &_con_hostname : NULL, \ + nmtst_get_rand_bool() ? &_con_carrier_timeout_sec : NULL, \ + NULL, \ + NULL, \ + NULL); \ + g_assert_cmpstr(_con_hostname, ==, NULL); \ + g_assert_cmpint(_con_carrier_timeout_sec, ==, 0); \ + \ + _con_connections; \ }) #define _parse_con(ARGV, connection_name) \ @@ -154,7 +164,7 @@ test_dhcp_with_hostname(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, "host1"); g_assert_cmpint(carrier_timeout_sec, ==, 0); @@ -424,7 +434,7 @@ test_if_ip4_manual(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, "hostname1.example.com"); g_assert_cmpint(carrier_timeout_sec, ==, 0); @@ -505,7 +515,7 @@ test_if_ip4_auto(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, "myhostname"); g_assert_cmpint(carrier_timeout_sec, ==, 0); @@ -596,7 +606,7 @@ test_if_ip6_manual(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, "hostname0.example.com"); g_assert_cmpint(carrier_timeout_sec, ==, 0); @@ -684,7 +694,7 @@ test_if_mac_ifname(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 1); g_assert_cmpstr(hostname, ==, "hostname0"); g_assert_cmpint(carrier_timeout_sec, ==, 0); @@ -1840,7 +1850,7 @@ test_rd_znet(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, "foo.example.com"); g_assert_cmpint(carrier_timeout_sec, ==, 0); @@ -1927,7 +1937,7 @@ test_rd_znet_legacy(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 2); g_assert_cmpstr(hostname, ==, "foo.example.com"); g_assert_cmpint(carrier_timeout_sec, ==, 0); @@ -2006,7 +2016,7 @@ test_rd_znet_ifnames(void) gint64 carrier_timeout_sec = 0; const char *const *v_subchannels; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 2); connection = g_hash_table_lookup(connections, "zeth0"); @@ -2281,7 +2291,7 @@ test_nameserver(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 3); g_assert_cmpstr(hostname, ==, "foo.example.com"); g_assert_cmpint(carrier_timeout_sec, ==, 0); @@ -2460,12 +2470,49 @@ test_carrier_timeout(void) gs_free char *hostname = NULL; gint64 carrier_timeout_sec = 0; - connections = _parse(ARGV, &hostname, &carrier_timeout_sec); + connections = _parse(ARGV, &hostname, &carrier_timeout_sec, NULL, NULL, NULL); g_assert_cmpint(g_hash_table_size(connections), ==, 0); g_assert_cmpstr(hostname, ==, NULL); g_assert_cmpint(carrier_timeout_sec, ==, 20); } +static void +test_global_dns(void) +{ + gs_unref_hashtable GHashTable *connections = NULL; + const char *const *ARGV = NM_MAKE_STRV("rd.net.dns=dns+tls://8.8.8.8", + "rd.net.dns=1.1.1.1", + "rd.net.dns=foobar", + "rd.net.dns=dns+tls://[fd01::1]:35#name", + "rd.net.dns-backend=dnsconfd", + "rd.net.dns-resolve-mode=exclusive"); + gs_free char *hostname = NULL; + gs_strfreev char **global_dns_servers = NULL; + gs_free char *dns_backend = NULL; + gs_free char *dns_resolve_mode = NULL; + gint64 carrier_timeout_sec = 0; + + NMTST_EXPECT_NM_WARN("cmdline-reader: rd.net.dns: invalid server 'foobar'"); + connections = _parse(ARGV, + &hostname, + &carrier_timeout_sec, + &global_dns_servers, + &dns_backend, + &dns_resolve_mode); + g_test_assert_expected_messages(); + + g_assert_cmpint(g_hash_table_size(connections), ==, 0); + g_assert_cmpstr(hostname, ==, NULL); + g_assert_cmpint(carrier_timeout_sec, ==, 0); + g_assert(global_dns_servers != NULL); + g_assert_cmpstr(global_dns_servers[0], ==, "dns+tls://8.8.8.8"); + g_assert_cmpstr(global_dns_servers[1], ==, "1.1.1.1"); + g_assert_cmpstr(global_dns_servers[2], ==, "dns+tls://[fd01::1]:35#name"); + g_assert_cmpstr(global_dns_servers[3], ==, NULL); + g_assert_cmpstr(dns_backend, ==, "dnsconfd"); + g_assert_cmpstr(dns_resolve_mode, ==, "exclusive"); +} + #define _ethtool_check_inval(arg) \ G_STMT_START \ { \ @@ -2686,6 +2733,7 @@ main(int argc, char **argv) g_test_add_func("/initrd/cmdline/carrier_timeout", test_carrier_timeout); g_test_add_func("/initrd/cmdline/rd_ethtool", test_rd_ethtool); g_test_add_func("/initrd/cmdline/plain_equal_char", test_plain_equal_char); + g_test_add_func("/initrd/cmdline/global_dns", test_global_dns); return g_test_run(); } diff --git a/src/nm-priv-helper/nm-priv-helper.c b/src/nm-priv-helper/nm-priv-helper.c index e29113b1..2fe9bcf5 100644 --- a/src/nm-priv-helper/nm-priv-helper.c +++ b/src/nm-priv-helper/nm-priv-helper.c @@ -234,7 +234,7 @@ _bus_find_nm_nameowner(GlobalData *gl) gl, NULL); - data = (BusFindNMNameOwnerData){ + data = (BusFindNMNameOwnerData) { .gl = gl, .is_cancelled = FALSE, .p_name_owner = &name_owner, diff --git a/src/nmcli/common.c b/src/nmcli/common.c index fbabdffc..2ced70f3 100644 --- a/src/nmcli/common.c +++ b/src/nmcli/common.c @@ -355,7 +355,7 @@ print_ip_config(NMIPConfig *cfg, } if (!nmc_print_table(nmc_config, - (gpointer[]){cfg, NULL}, + (gpointer[]) {cfg, NULL}, NULL, NULL, addr_family == AF_INET @@ -386,7 +386,7 @@ print_dhcp_config(NMDhcpConfig *dhcp, } if (!nmc_print_table(nmc_config, - (gpointer[]){dhcp, NULL}, + (gpointer[]) {dhcp, NULL}, NULL, NULL, addr_family == AF_INET @@ -1399,7 +1399,7 @@ call_cmd(NmCli *nmc, GTask *task, const NMCCommand *cmd, int argc, const char *c nmc->should_wait++; call = g_slice_new(CmdCall); - *call = (CmdCall){ + *call = (CmdCall) { .cmd = cmd, .argc = argc, .argv = nm_strv_dup(argv, argc, TRUE), @@ -1430,7 +1430,7 @@ call_cmd(NmCli *nmc, GTask *task, const NMCCommand *cmd, int argc, const char *c nmc->should_wait++; call = g_slice_new(CmdCall); - *call = (CmdCall){ + *call = (CmdCall) { .cmd = cmd, .argc = argc, .argv = nm_strv_dup(argv, argc, TRUE), diff --git a/src/nmcli/common.h b/src/nmcli/common.h index 3784da35..892b2d4e 100644 --- a/src/nmcli/common.h +++ b/src/nmcli/common.h @@ -70,7 +70,7 @@ nmc_do_cmd(NmCli *nmc, const NMCCommand cmds[], const char *cmd, int argc, const void nmc_complete_strv(const char *prefix, gssize nargs, const char *const *args); #define nmc_complete_strings(prefix, ...) \ - nmc_complete_strv((prefix), NM_NARG(__VA_ARGS__), (const char *const[]){__VA_ARGS__}) + nmc_complete_strv((prefix), NM_NARG(__VA_ARGS__), (const char *const[]) {__VA_ARGS__}) void nmc_complete_bool(const char *prefix); diff --git a/src/nmcli/connections.c b/src/nmcli/connections.c index 002dd402..bccec3a1 100644 --- a/src/nmcli/connections.c +++ b/src/nmcli/connections.c @@ -113,7 +113,7 @@ _add_connection_info_new(NmCli *nmc, NMConnection *orig_connection, NMConnection AddConnectionInfo *info; info = g_slice_new(AddConnectionInfo); - *info = (AddConnectionInfo){ + *info = (AddConnectionInfo) { .nmc = nmc, .orig_id = orig_connection ? g_strdup(nm_connection_get_id(orig_connection)) : NULL, .orig_uuid = orig_connection ? g_strdup(nm_connection_get_uuid(orig_connection)) : NULL, @@ -1075,7 +1075,7 @@ const NmcMetaGenericInfo "," NM_SETTING_PROXY_SETTING_NAME "," NM_SETTING_TC_CONFIG_SETTING_NAME \ "," NM_SETTING_SRIOV_SETTING_NAME "," NM_SETTING_ETHTOOL_SETTING_NAME \ "," NM_SETTING_OVS_DPDK_SETTING_NAME "," NM_SETTING_HOSTNAME_SETTING_NAME \ - "," NM_SETTING_HSR_SETTING_NAME + "," NM_SETTING_HSR_SETTING_NAME "," NM_SETTING_IPVLAN_SETTING_NAME /* NM_SETTING_DUMMY_SETTING_NAME NM_SETTING_WIMAX_SETTING_NAME */ const NmcMetaGenericInfo *const nmc_fields_con_active_details_groups[] = { @@ -1763,7 +1763,7 @@ nmc_active_connection_details(NMActiveConnection *acon, NmCli *nmc) nmc_print_table( &nmc->nmc_config, - (gpointer[]){acon, NULL}, + (gpointer[]) {acon, NULL}, NULL, NULL, NMC_META_GENERIC_GROUP("GENERAL", metagen_con_active_general, N_("GROUP")), @@ -1820,7 +1820,7 @@ nmc_active_connection_details(NMActiveConnection *acon, NmCli *nmc) if (nmc_fields_con_active_details_groups[group_idx]->nested == metagen_con_active_vpn) { if (NM_IS_VPN_CONNECTION(acon)) { nmc_print_table(&nmc->nmc_config, - (gpointer[]){acon, NULL}, + (gpointer[]) {acon, NULL}, NULL, NULL, NMC_META_GENERIC_GROUP("VPN", metagen_con_active_vpn, N_("NAME")), @@ -1883,8 +1883,23 @@ split_required_fields_for_con_show(const char *input, for (i = 0; i < _NM_META_SETTING_TYPE_NUM; i++) { if (is_all || is_common || !g_ascii_strcasecmp(s_mutable, nm_meta_setting_infos[i].setting_name)) { - if (dot) + gs_free char *to_free = NULL; + + if (dot) { + /* If there was a dot we have 'setting.property'. Some properties has different + * name for the user than internally in libnm and D-Bus. Make the conversion + * from user names to libnm names. + */ + const char *prop_user = dot + 1; + const char *prop_libnm = + nmc_setting_propname_user_to_libnm(s_mutable, prop_user); + if (prop_user != prop_libnm) { + to_free = g_strdup_printf("%s.%s", s_mutable, prop_libnm); + s_mutable = to_free; + } *dot = '.'; + } + g_string_append(str1, s_mutable); g_string_append_c(str1, ','); found = TRUE; @@ -3143,9 +3158,6 @@ do_connection_up(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const const char *pwds = NULL; gs_free_error GError *error = NULL; gs_strfreev char **arg_arr = NULL; - int arg_num; - const char *const **argv_ptr; - int *argc_ptr; /* * Set default timeout for connection activation. @@ -3155,8 +3167,6 @@ do_connection_up(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const nmc->timeout = 90; next_arg(nmc, &argc, &argv, NULL); - argv_ptr = &argv; - argc_ptr = &argc; if (argc == 0 && nmc->ask) { gs_free char *line = NULL; @@ -3165,13 +3175,12 @@ do_connection_up(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const g_return_if_fail(!nmc->complete); line = nmc_readline(&nmc->nmc_config, PROMPT_CONNECTION); - nmc_string_to_arg_array(line, NULL, TRUE, &arg_arr, &arg_num); - argv_ptr = (const char *const **) &arg_arr; - argc_ptr = &arg_num; + nmc_string_to_arg_array(line, NULL, TRUE, &arg_arr, &argc); + argv = (const char *const *) arg_arr; } if (argc > 0 && !nm_streq(*argv, "ifname")) { - connection = get_connection(nmc, argc_ptr, argv_ptr, NULL, NULL, NULL, &error); + connection = get_connection(nmc, &argc, &argv, NULL, NULL, NULL, &error); if (!connection) { g_string_printf(nmc->return_text, _("Error: %s."), error->message); nmc->return_value = error->code; @@ -4398,7 +4407,7 @@ set_property(NMClient *client, } /* Don't ask for this property in interactive mode. */ - disable_options(setting_name, property_name); + disable_options(setting_name, nmc_setting_propname_user_to_libnm(setting_name, property_name)); return TRUE; } @@ -6919,7 +6928,7 @@ nmcli_editor_tab_completion(const char *text, int start, int end) return match_array; } -#define NMCLI_EDITOR_HISTORY ".nmcli-history" +#define NMCLI_EDITOR_HISTORY "nmcli-history" static void load_history_cmds(const char *uuid) @@ -6931,7 +6940,7 @@ load_history_cmds(const char *uuid) size_t i; GError *err = NULL; - filename = g_build_filename(g_get_home_dir(), NMCLI_EDITOR_HISTORY, NULL); + filename = g_build_filename(g_get_user_cache_dir(), NMCLI_EDITOR_HISTORY, NULL); kf = g_key_file_new(); if (!g_key_file_load_from_file(kf, filename, G_KEY_FILE_KEEP_COMMENTS, &err)) { if (g_error_matches(err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE)) @@ -6967,7 +6976,7 @@ save_history_cmds(const char *uuid) if (!hist) return; - filename = g_build_filename(g_get_home_dir(), NMCLI_EDITOR_HISTORY, NULL); + filename = g_build_filename(g_get_user_cache_dir(), NMCLI_EDITOR_HISTORY, NULL); kf = g_key_file_new(); diff --git a/src/nmcli/devices.c b/src/nmcli/devices.c index f6163757..b308e440 100644 --- a/src/nmcli/devices.c +++ b/src/nmcli/devices.c @@ -1675,7 +1675,7 @@ show_device_info(NMDevice *device, NmCli *nmc) nmc_print_table( &nmc->nmc_config, - (gpointer[]){device, NULL}, + (gpointer[]) {device, NULL}, NULL, NULL, NMC_META_GENERIC_GROUP("GENERAL", metagen_device_detail_general, N_("NAME")), @@ -1690,7 +1690,7 @@ show_device_info(NMDevice *device, NmCli *nmc) gs_free char *f = section_fld ? g_strdup_printf("CAPABILITIES.%s", section_fld) : NULL; nmc_print_table(&nmc->nmc_config, - (gpointer[]){device, NULL}, + (gpointer[]) {device, NULL}, NULL, NULL, NMC_META_GENERIC_GROUP("CAPABILITIES", @@ -1708,7 +1708,7 @@ show_device_info(NMDevice *device, NmCli *nmc) section_fld ? g_strdup_printf("INTERFACE-FLAGS.%s", section_fld) : NULL; nmc_print_table(&nmc->nmc_config, - (gpointer[]){device, NULL}, + (gpointer[]) {device, NULL}, NULL, NULL, NMC_META_GENERIC_GROUP("INTERFACE-FLAGS", @@ -1727,7 +1727,7 @@ show_device_info(NMDevice *device, NmCli *nmc) section_fld ? g_strdup_printf("WIFI-PROPERTIES.%s", section_fld) : NULL; nmc_print_table(&nmc->nmc_config, - (gpointer[]){device, NULL}, + (gpointer[]) {device, NULL}, NULL, NULL, NMC_META_GENERIC_GROUP("WIFI-PROPERTIES", @@ -1791,7 +1791,7 @@ show_device_info(NMDevice *device, NmCli *nmc) section_fld ? g_strdup_printf("WIRED-PROPERTIES.%s", section_fld) : NULL; nmc_print_table(&nmc->nmc_config, - (gpointer[]){device, NULL}, + (gpointer[]) {device, NULL}, NULL, NULL, NMC_META_GENERIC_GROUP("WIRED-PROPERTIES", @@ -1920,7 +1920,7 @@ show_device_info(NMDevice *device, NmCli *nmc) gs_free char *f = section_fld ? g_strdup_printf("CONNECTIONS.%s", section_fld) : NULL; nmc_print_table(&nmc->nmc_config, - (gpointer[]){device, NULL}, + (gpointer[]) {device, NULL}, NULL, NULL, NMC_META_GENERIC_GROUP("CONNECTIONS", @@ -2102,7 +2102,7 @@ add_and_activate_info_new(NmCli *nmc, AddAndActivateInfo *info; info = g_slice_new(AddAndActivateInfo); - *info = (AddAndActivateInfo){ + *info = (AddAndActivateInfo) { .nmc = nmc, .device = g_object_ref(device), .hotspot = hotspot, @@ -2639,7 +2639,7 @@ do_device_modify(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const nmc->should_wait++; info = g_slice_new(ModifyInfo); - *info = (ModifyInfo){ + *info = (ModifyInfo) { .nmc = nmc, .argc = argc, .argv = nm_strv_dup(argv, argc, TRUE), @@ -3535,7 +3535,7 @@ do_device_wifi_list(const NMCCommand *cmd, NmCli *nmc, int argc, const char *con } scan_info = g_slice_new(ScanInfo); - *scan_info = (ScanInfo){ + *scan_info = (ScanInfo) { .out_indices = g_array_ref(out_indices), .tmpl = tmpl, .bssid_user = g_strdup(bssid_user), @@ -3557,7 +3557,7 @@ do_device_wifi_list(const NMCCommand *cmd, NmCli *nmc, int argc, const char *con timeout_msec = 15000; wifi_list_data = g_slice_new(WifiListData); - *wifi_list_data = (WifiListData){ + *wifi_list_data = (WifiListData) { .wifi = wifi, .scan_info = scan_info, .timeout_id = g_timeout_add(timeout_msec, wifi_list_scan_timeout, wifi_list_data), @@ -4113,7 +4113,7 @@ generate_wpa_key(char *key, size_t len) int c; do { - c = nm_random_u64_range_full(48, 122, TRUE); + c = nm_random_u64_range(48, 122); /* skip characters that look similar */ } while (NM_IN_SET(c, '1', 'l', 'I', '0', 'O', 'Q', '8', 'B', '5', 'S') || !g_ascii_isalnum(c)); @@ -4136,7 +4136,7 @@ generate_wep_key(char *key, size_t len) for (i = 0; i < 10; i++) { int digit; - digit = nm_random_u64_range_full(0, 16, TRUE); + digit = nm_random_u64_range(0, 16); key[i] = hexdigits[digit]; } key[10] = '\0'; diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.c b/src/nmcli/gen-metadata-nm-settings-nmcli.c index 1764da73..2ba95995 100644 --- a/src/nmcli/gen-metadata-nm-settings-nmcli.c +++ b/src/nmcli/gen-metadata-nm-settings-nmcli.c @@ -124,6 +124,8 @@ get_ethtool_format(const NMMetaPropertyInfo *prop_info) case NM_ETHTOOL_TYPE_PAUSE: case NM_ETHTOOL_TYPE_EEE: return g_strdup("ternary"); + case NM_ETHTOOL_TYPE_FEC: + return g_strdup("flags (NMSettingEthtoolFecMode)"); case NM_ETHTOOL_TYPE_UNKNOWN: nm_assert_not_reached(); }; @@ -158,6 +160,8 @@ get_multilist_format(const NMMetaPropertyInfo *prop_info) return g_strdup("list of IPv4 addresses"); case NM_META_PROPERTY_TYPE_FORMAT_IPV6: return g_strdup("list of IPv6 addresses"); + case NM_META_PROPERTY_TYPE_FORMAT_IPV4_IPV6: + return g_strdup("list of IPv4 or IPv6 addresses"); default: prop_abort(prop_info, "unsupported item format (%d)", item_fmt); break; @@ -198,6 +202,8 @@ get_property_format(const NMMetaPropertyInfo *prop_info) return g_strdup("IPv4 address"); case NM_META_PROPERTY_TYPE_FORMAT_IPV6: return g_strdup("IPv6 address"); + case NM_META_PROPERTY_TYPE_FORMAT_IPV4_IPV6: + return g_strdup("IPv4 or IPv6 address"); case NM_META_PROPERTY_TYPE_FORMAT_BYTES: return g_strdup("bytes"); case NM_META_PROPERTY_TYPE_FORMAT_PATH: @@ -330,6 +336,13 @@ append_ethtool_valid_values(const NMMetaPropertyInfo *prop_info, GPtrArray *vali case NM_ETHTOOL_TYPE_EEE: append_vals(valid_values, "on", "off", "ignore"); break; + case NM_ETHTOOL_TYPE_FEC: + _append_enum_valid_values(NM_TYPE_SETTING_ETHTOOL_FEC_MODE, + 0, + G_MAXUINT, + NULL, + valid_values); + break; case NM_ETHTOOL_TYPE_UNKNOWN: nm_assert_not_reached(); } diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in index ae3a388b..9aa1751e 100644 --- a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in +++ b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in @@ -629,7 +629,7 @@ alias="type" nmcli-description="Base type of the connection. For hardware-dependent connections, should contain the setting name of the hardware-type specific setting (ie, "802-3-ethernet" or "802-11-wireless" or "bluetooth", etc), and for non-hardware dependent connections like VPN or otherwise, should contain the setting name of that setting type (ie, "vpn" or "bridge", etc)." format="string" - values="6lowpan, 802-11-olpc-mesh, 802-11-wireless, 802-3-ethernet, adsl, bluetooth, bond, bridge, cdma, dummy, generic, gsm, hsr, infiniband, ip-tunnel, loopback, macsec, macvlan, ovs-bridge, ovs-dpdk, ovs-interface, ovs-patch, ovs-port, pppoe, team, tun, veth, vlan, vpn, vrf, vxlan, wifi-p2p, wimax, wireguard, wpan" /> + values="6lowpan, 802-11-olpc-mesh, 802-11-wireless, 802-3-ethernet, adsl, bluetooth, bond, bridge, cdma, dummy, generic, gsm, hsr, infiniband, ip-tunnel, ipvlan, loopback, macsec, macvlan, ovs-bridge, ovs-dpdk, ovs-interface, ovs-patch, ovs-port, pppoe, team, tun, veth, vlan, vpn, vrf, vxlan, wifi-p2p, wimax, wireguard, wpan" /> <property name="interface-name" alias="ifname" nmcli-description="The name of the network interface this connection is bound to. If not set, then the connection can be attached to any interface of the appropriate type (subject to restrictions imposed by other settings). For software devices this specifies the name of the created device. For connection types where interface names cannot easily be made persistent (e.g. mobile broadband or USB Ethernet), this property should not be used. Setting this property restricts the interfaces a connection can be used with, and if interface names change or are reordered the connection may be applied to the wrong interface." @@ -702,6 +702,17 @@ nmcli-description="If greater than zero, delay success of IP addressing until either the timeout is reached, or an IP gateway replies to a ping." format="integer" values="0 - 600" /> + <property name="ip-ping-timeout" + nmcli-description="If greater than zero, delay success of IP addressing until either the specified timeout (in seconds) is reached, or a target IP address replies to a ping. The property specifies the timeout for the "ip-ping-addresses". This property is incompatible with "gateway-ping-timeout", you cannot set these two properties at the same time." + format="integer" + values="0 - 600" /> + <property name="ip-ping-addresses" + nmcli-description="The property specifies a list of target IP addresses for pinging. When multiple targets are set, NetworkManager will start multiple ping processes in parallel. This property can only be set if connection.ip-ping-timeout is set. The ip-ping-timeout is used to delay the success of IP addressing until either the specified timeout (in seconds) is reached, or an target IP address replies to a ping. Configuring "ip-ping-addresses" may delay reaching the systemd's network-online.target due to waiting for the ping operations to complete or timeout." + format="list of IPv4 or IPv6 addresses" /> + <property name="ip-ping-addresses-require-all" + nmcli-description="The property determines whether it is sufficient for any ping check to succeed among "ip-ping-addresses", or if all ping checks must succeed for "ip-ping-addresses"." + format="choice (NMTernary)" + values="default (-1), false/no (0), true/yes (1)" /> <property name="metered" nmcli-description="Whether the connection is metered. When updating this property on a currently activated connection, the change takes effect immediately." format="ternary" @@ -1085,6 +1096,10 @@ <property name="channels-combined" format="integer" values="0 - 4294967295" /> + <property name="fec-mode" + nmcli-description="The Forward Error Correction(FEC) encoding modes to set. Not all devices support all options. May be any combination of auto, off, rs, baser, llrs." + format="flags (NMSettingEthtoolFecMode)" + values="auto (0x2), off (0x4), rs (0x8), baser (0x10), llrs (0x20)" /> </setting> <setting name="generic" > <property name="device-handler" @@ -1149,6 +1164,40 @@ <property name="initial-eps-bearer-apn" nmcli-description="For LTE modems, this sets the APN for the initial EPS bearer that is set up when attaching to the network. Setting this parameter implies initial-eps-bearer-configure to be TRUE." format="string" /> + <property name="initial-eps-bearer-username" + nmcli-description="For LTE modems, this sets the username for the initial EPS bearer that is set up when attaching to the network. Setting this parameter implies initial-eps-bearer-configure to be TRUE." + format="string" /> + <property name="initial-eps-bearer-password" + nmcli-description="For LTE modems, this sets the password for the initial EPS bearer that is set up when attaching to the network. Setting this parameter implies initial-eps-bearer-configure to be TRUE." + format="string" /> + <property name="initial-eps-bearer-password-flags" + nmcli-description="Flags indicating how to handle the "initial-eps-bearer-password" property." + format="flags (NMSettingSecretFlags)" + values="none (0x0), agent-owned (0x1), not-saved (0x2), not-required (0x4)" /> + <property name="initial-eps-bearer-noauth" + nmcli-description="For LTE modems, this sets NOAUTH authentication method for the initial EPS bearer that is set up when attaching to the network. If TRUE, do not require the other side to authenticate itself to the client. If FALSE, require authentication from the remote side. In almost all cases, this should be TRUE." + format="boolean" + values="true/yes/on, false/no/off" /> + <property name="initial-eps-bearer-refuse-eap" + nmcli-description="For LTE modems, this disables EAP authentication method for the initial EPS bearer that is set up when attaching to the network." + format="boolean" + values="true/yes/on, false/no/off" /> + <property name="initial-eps-bearer-refuse-pap" + nmcli-description="For LTE modems, this disables PAP authentication method for the initial EPS bearer that is set up when attaching to the network." + format="boolean" + values="true/yes/on, false/no/off" /> + <property name="initial-eps-bearer-refuse-chap" + nmcli-description="For LTE modems, this disables CHAP authentication method for the initial EPS bearer that is set up when attaching to the network." + format="boolean" + values="true/yes/on, false/no/off" /> + <property name="initial-eps-bearer-refuse-mschap" + nmcli-description="For LTE modems, this disables MSCHAP authentication method for the initial EPS bearer that is set up when attaching to the network." + format="boolean" + values="true/yes/on, false/no/off" /> + <property name="initial-eps-bearer-refuse-mschapv2" + nmcli-description="For LTE modems, this disables MSCHAPV2 authentication method for the initial EPS bearer that is set up when attaching to the network." + format="boolean" + values="true/yes/on, false/no/off" /> </setting> <setting name="hostname" > <property name="priority" @@ -1276,7 +1325,7 @@ format="string" values="auto, link-local, manual, shared, disabled" /> <property name="dns" - nmcli-description="Array of IP addresses of DNS servers. For DoT (DNS over TLS), the SNI server name can be specified by appending "#example.com" to the IP address of the DNS server. This currently only has effect when using systemd-resolved." + nmcli-description="Array of DNS servers. Each server can be specified either as a plain IP address (optionally followed by a "#" and the SNI server name for DNS over TLS) or with a URI syntax. When it is specified as an URI, the following forms are supported: dns+udp://ADDRESS[:PORT], dns+tls://ADDRESS[:PORT][SERVERNAME] . When using the URI syntax, IPv6 addresses must be enclosed in square brackets ('[', ']')." format="list of IPv4 addresses" /> <property name="dns-search" nmcli-description="List of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names. When using a DNS plugin that supports Conditional Forwarding or Split DNS, then the search domains specify which name servers to query. This makes the behavior different from running with plain /etc/resolv.conf. For more information see also the dns-priority setting. When set on a profile that also enabled DHCP, the DNS search list received automatically (option 119 for DHCPv4 and option 24 for DHCPv6) gets merged with the manual list. This can be prevented by setting "ignore-auto-dns". Note that if no DNS searches are configured, the fallback will be derived from the domain from DHCP (option 15)." @@ -1318,6 +1367,10 @@ nmcli-description="Whether the DHCP client will send RELEASE message when bringing the connection down. The default value is "default" (-1). When the default value is specified, then the global value from NetworkManager configuration is looked up, if not set, it is considered as FALSE." format="ternary" values="true/yes/on, false/no/off, default/unknown" /> + <property name="routed-dns" + nmcli-description="Whether to add routes for DNS servers. When enabled, NetworkManager adds a route for each DNS server that is associated with this connection either statically (defined in the connection profile) or dynamically (for example, retrieved via DHCP). The route guarantees that the DNS server is reached via this interface. When set to "default" (-1), the value from global configuration is used; if no global default is defined, this feature is disabled." + format="choice (NMSettingIPConfigRoutedDns)" + values="default (-1), no (0), yes (1)" /> <property name="ignore-auto-routes" nmcli-description="When "method" is set to "auto" and this property to TRUE, automatically configured routes are ignored and only routes specified in the "routes" property, if any, are used." format="boolean" @@ -1342,9 +1395,13 @@ values="0 - 2147483647" special-values="default (0), infinity (2147483647)" /> <property name="dhcp-send-hostname" - nmcli-description="If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the "dhcp-hostname" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent." + nmcli-description="Since 1.52 this property is deprecated and is only used as fallback value for dhcp-send-hostname if it's set to 'default'. This is only done to avoid breaking existing configurations, the new property should be used from now on." format="boolean" values="true/yes/on, false/no/off" /> + <property name="dhcp-send-hostname-v2" + nmcli-description="If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the dhcp-hostname property is NULL and this property is TRUE, the current persistent hostname of the computer is sent. The default value is default (-1). In this case the global value from NetworkManager configuration is looked up. If it's not set, the value from dhcp-send-hostname-deprecated, which defaults to TRUE, is used for backwards compatibility. In the future this will change and, in absence of a global default, it will always fallback to TRUE." + format="choice (NMTernary)" + values="default (-1), false/no (0), true/yes (1)" /> <property name="dhcp-hostname" nmcli-description="If the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and "dhcp-fqdn" are mutually exclusive and cannot be set at the same time." format="string" /> @@ -1376,10 +1433,14 @@ <property name="dhcp-vendor-class-identifier" nmcli-description="The Vendor Class Identifier DHCP option (60). Special characters in the data string may be escaped using C-style escapes, nevertheless this property cannot contain nul bytes. If the per-profile value is unspecified (the default), a global connection default gets consulted. If still unspecified, the DHCP option is not sent to the server." format="string" /> + <property name="dhcp-ipv6-only-preferred" + nmcli-description="Controls the "IPv6-Only Preferred" DHCPv4 option (RFC 8925). When set to "yes" (1), the host adds the option to the parameter request list; if the DHCP server sends the option back, the host stops the DHCP client for the time interval specified in the option. Enable this feature if the host supports an IPv6-only mode, i.e. either all applications are IPv6-only capable or there is a form of 464XLAT deployed. When set to "default" (-1), the actual value is looked up in the global configuration; if not specified, it defaults to "no" (0). If the connection has IPv6 method set to "disabled", this property does not have effect and the "IPv6-Only Preferred" option is always disabled." + format="choice (NMSettingIP4DhcpIpv6OnlyPreferred)" + values="default (-1), no (0), yes (1)" /> <property name="link-local" - nmcli-description="Enable and disable the IPv4 link-local configuration independently of the ipv4.method configuration. This allows a link-local address (169.254.x.y/16) to be obtained in addition to other addresses, such as those manually configured or obtained from a DHCP server. When set to "auto", the value is dependent on "ipv4.method". When set to "default", it honors the global connection default, before falling back to "auto". Note that if "ipv4.method" is "disabled", then link local addressing is always disabled too. The default is "default"." + nmcli-description="Enable and disable the IPv4 link-local configuration independently of the ipv4.method configuration. This allows a link-local address (169.254.x.y/16) to be obtained in addition to other addresses, such as those manually configured or obtained from a DHCP server. When set to "auto", the value is dependent on "ipv4.method". When set to "default", it honors the global connection default, before falling back to "auto". Note that if "ipv4.method" is "disabled", then link local addressing is always disabled too. The default is "default". Since 1.52, when set to "fallback", a link-local address is obtained if no other IPv4 address is set." format="choice (NMSettingIP4LinkLocal)" - values="default (0), auto (1), disabled (2), enabled (3)" /> + values="default (0), auto (1), disabled (2), enabled (3), fallback (4)" /> <property name="dhcp-reject-servers" nmcli-description="Array of servers from which DHCP offers must be rejected. This property is useful to avoid getting a lease from misconfigured or rogue servers. For DHCPv4, each element must be an IPv4 address, optionally followed by a slash and a prefix length (e.g. "192.168.122.0/24"). This property is currently not implemented for DHCPv6." format="list of IPv4 addresses" /> @@ -1387,6 +1448,14 @@ nmcli-description="VPN connections will default to add the route automatically unless this setting is set to FALSE. For other connection types, adding such an automatic route is currently not supported and setting this to TRUE has no effect." format="ternary" values="true/yes/on, false/no/off, default/unknown" /> + <property name="shared-dhcp-range" + nmcli-description="This option allows you to specify a custom DHCP range for the shared connection method. The value is expected to be in `<START_ADDRESS>,<END_ADDRESS>` format. The range should be part of network set by ipv4.address option and it should not contain network address or broadcast address. If this option is not specified, the DHCP range will be automatically determined based on the interface address. The range will be selected to be adjacent to the interface address, either before or after it, with the larger possible range being preferred. The range will be adjusted to fill the available address space, except for networks with a prefix length greater than 24, which will be treated as if they have a prefix length of 24." + format="string" /> + <property name="shared-dhcp-lease-time" + nmcli-description="This option allows you to specify a custom DHCP lease time for the shared connection method in seconds. The value should be either a number between 120 and 31536000 (one year) If this option is not specified, 3600 (one hour) is used. Special values are 0 for default value of 1 hour and 2147483647 (MAXINT32) for infinite lease time." + format="integer" + values="0 - 2147483647" + special-values="default (0), infinity (2147483647)" /> </setting> <setting name="ipv6" > <property name="method" @@ -1394,7 +1463,7 @@ format="string" values="ignore, auto, dhcp, link-local, manual, shared, disabled" /> <property name="dns" - nmcli-description="Array of IP addresses of DNS servers. For DoT (DNS over TLS), the SNI server name can be specified by appending "#example.com" to the IP address of the DNS server. This currently only has effect when using systemd-resolved." + nmcli-description="Array of DNS servers. Each server can be specified either as a plain IP address (optionally followed by a "#" and the SNI server name for DNS over TLS) or with a URI syntax. When it is specified as an URI, the following forms are supported: dns+udp://ADDRESS[:PORT], dns+tls://ADDRESS[:PORT][SERVERNAME] . When using the URI syntax, IPv6 addresses must be enclosed in square brackets ('[', ']')." format="list of IPv6 addresses" /> <property name="dns-search" nmcli-description="List of DNS search domains. Domains starting with a tilde ('~') are considered 'routing' domains and are used only to decide the interface over which a query must be forwarded; they are not used to complete unqualified host names. When using a DNS plugin that supports Conditional Forwarding or Split DNS, then the search domains specify which name servers to query. This makes the behavior different from running with plain /etc/resolv.conf. For more information see also the dns-priority setting. When set on a profile that also enabled DHCP, the DNS search list received automatically (option 119 for DHCPv4 and option 24 for DHCPv6) gets merged with the manual list. This can be prevented by setting "ignore-auto-dns". Note that if no DNS searches are configured, the fallback will be derived from the domain from DHCP (option 15)." @@ -1436,6 +1505,10 @@ nmcli-description="Whether the DHCP client will send RELEASE message when bringing the connection down. The default value is "default" (-1). When the default value is specified, then the global value from NetworkManager configuration is looked up, if not set, it is considered as FALSE." format="ternary" values="true/yes/on, false/no/off, default/unknown" /> + <property name="routed-dns" + nmcli-description="Whether to add routes for DNS servers. When enabled, NetworkManager adds a route for each DNS server that is associated with this connection either statically (defined in the connection profile) or dynamically (for example, retrieved via DHCP). The route guarantees that the DNS server is reached via this interface. When set to "default" (-1), the value from global configuration is used; if no global default is defined, this feature is disabled." + format="choice (NMSettingIPConfigRoutedDns)" + values="default (-1), no (0), yes (1)" /> <property name="ignore-auto-routes" nmcli-description="When "method" is set to "auto" and this property to TRUE, automatically configured routes are ignored and only routes specified in the "routes" property, if any, are used." format="boolean" @@ -1499,9 +1572,13 @@ values="0 - 2147483647" special-values="default (0), infinity (2147483647)" /> <property name="dhcp-send-hostname" - nmcli-description="If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the "dhcp-hostname" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent." + nmcli-description="Since 1.52 this property is deprecated and is only used as fallback value for dhcp-send-hostname if it's set to 'default'. This is only done to avoid breaking existing configurations, the new property should be used from now on." format="boolean" values="true/yes/on, false/no/off" /> + <property name="dhcp-send-hostname-v2" + nmcli-description="If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the dhcp-hostname property is NULL and this property is TRUE, the current persistent hostname of the computer is sent. The default value is default (-1). In this case the global value from NetworkManager configuration is looked up. If it's not set, the value from dhcp-send-hostname-deprecated, which defaults to TRUE, is used for backwards compatibility. In the future this will change and, in absence of a global default, it will always fallback to TRUE." + format="choice (NMTernary)" + values="default (-1), false/no (0), true/yes (1)" /> <property name="dhcp-hostname" nmcli-description="If the "dhcp-send-hostname" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and "dhcp-fqdn" are mutually exclusive and cannot be set at the same time." format="string" /> @@ -1517,6 +1594,25 @@ nmcli-description="Configure the token for draft-chown-6man-tokenised-ipv6-identifiers-02 IPv6 tokenized interface identifiers. Useful with eui64 addr-gen-mode. When set, the token is used as IPv6 interface identifier instead of the hardware address. This only applies to addresses from stateless autoconfiguration, not to IPv6 link local addresses." format="string" /> </setting> + <setting name="ipvlan" > + <property name="parent" + alias="dev" + nmcli-description="If given, specifies the parent interface name or parent connection UUID from which this IPVLAN interface should be created. If this property is not specified, the connection must contain an "802-3-ethernet" setting with a "mac-address" property." + format="string" /> + <property name="mode" + alias="mode" + nmcli-description="The IPVLAN mode. Valid values: l2 (1), l3 (2), l3s (3)" + format="choice (NMSettingIpvlanMode)" + values="l2 (1), l3 (2), l3s (3)" /> + <property name="private" + nmcli-description="Whether the interface should be put in private mode." + format="boolean" + values="true/yes/on, false/no/off" /> + <property name="vepa" + nmcli-description="Whether the interface should be put in VEPA mode." + format="boolean" + values="true/yes/on, false/no/off" /> + </setting> <setting name="link" > <property name="gso-max-segments" nmcli-description="The maximum segments of a Generic Segment Offload packet the device should accept. The value must be between 0 and 4294967295. When set to -1, the existing value is preserved." diff --git a/src/nmcli/general.c b/src/nmcli/general.c index ea070e05..c6c266a2 100644 --- a/src/nmcli/general.c +++ b/src/nmcli/general.c @@ -500,7 +500,7 @@ show_nm_status(NmCli *nmc, const char *pretty_header_name, const char *print_fld fields_str = nmc->required_fields; if (!nmc_print_table(&nmc->nmc_config, - (gpointer[]){nmc, NULL}, + (gpointer[]) {nmc, NULL}, NULL, pretty_header_name ?: N_("NetworkManager status"), (const NMMetaAbstractInfo *const *) metagen_general_status, @@ -733,7 +733,7 @@ show_general_logging(NmCli *nmc) fields_str = nmc->required_fields; if (!nmc_print_table(&nmc->nmc_config, - (gpointer const[]){&d, NULL}, + (gpointer const[]) {&d, NULL}, NULL, _("NetworkManager logging"), (const NMMetaAbstractInfo *const *) metagen_general_logging, diff --git a/src/nmcli/settings.c b/src/nmcli/settings.c index 636df466..85f4ad83 100644 --- a/src/nmcli/settings.c +++ b/src/nmcli/settings.c @@ -503,7 +503,7 @@ _env_get_env_flags(const NMMetaEnvironment *environment, gpointer environment_us /*****************************************************************************/ -const NMMetaEnvironment *const nmc_meta_environment = &((NMMetaEnvironment){ +const NMMetaEnvironment *const nmc_meta_environment = &((NMMetaEnvironment) { .warn_fcn = _env_warn_fcn_handle, .get_nm_devices = _env_get_nm_devices, .get_nm_connections = _env_get_nm_connections, @@ -525,6 +525,8 @@ get_property_val(NMSetting *setting, NM_IN_SET(get_type, NM_META_ACCESSOR_GET_TYPE_PARSABLE, NM_META_ACCESSOR_GET_TYPE_PRETTY), NULL); + prop = nmc_setting_propname_user_to_libnm(nm_setting_get_name(setting), prop); + if ((property_info = nm_meta_property_info_find_by_setting(setting, prop))) { if (property_info->property_type->get_fcn) { NMMetaAccessorGetOutFlags out_flags = NM_META_ACCESSOR_GET_OUT_FLAGS_NONE; @@ -593,8 +595,11 @@ nmc_setting_set_property(NMClient *client, NM_META_ACCESSOR_MODIFIER_ADD), FALSE); + prop = nmc_setting_propname_user_to_libnm(nm_setting_get_name(setting), prop); + if (!(property_info = nm_meta_property_info_find_by_setting(setting, prop))) goto out_fail_read_only; + if (!property_info->property_type->set_fcn) goto out_fail_read_only; @@ -661,8 +666,12 @@ nmc_setting_get_valid_properties(NMSetting *setting) num = setting_info ? setting_info->properties_num : 0; valid_props = g_new(char *, num + 1); - for (i = 0; i < num; i++) - valid_props[i] = g_strdup(setting_info->properties[i]->property_name); + for (i = 0; i < num; i++) { + const char *prop = + nmc_setting_propname_libnm_to_user(setting_info->general->setting_name, + setting_info->properties[i]->property_name); + valid_props[i] = g_strdup(prop); + } valid_props[num] = NULL; return valid_props; @@ -678,6 +687,8 @@ nmc_setting_get_property_allowed_values(NMSetting *setting, const char *prop, ch *out_to_free = NULL; + prop = nmc_setting_propname_user_to_libnm(nm_setting_get_name(setting), prop); + if ((property_info = nm_meta_property_info_find_by_setting(setting, prop))) { if (property_info->property_type->values_fcn) { return property_info->property_type->values_fcn(property_info, out_to_free); @@ -711,6 +722,8 @@ nmc_setting_get_property_desc(NMSetting *setting, const char *prop) g_return_val_if_fail(NM_IS_SETTING(setting), FALSE); + prop = nmc_setting_propname_user_to_libnm(nm_setting_get_name(setting), prop); + property_info = nm_meta_property_info_find_by_setting(setting, prop); if (!property_info) return NULL; @@ -764,13 +777,43 @@ setting_details(const NmcConfig *nmc_config, NMSetting *setting, const char *one if (!nmc_print_table( nmc_config, - (gpointer[]){setting, NULL}, + (gpointer[]) {setting, NULL}, NULL, NULL, - (const NMMetaAbstractInfo *const[]){(const NMMetaAbstractInfo *) setting_info, NULL}, + (const NMMetaAbstractInfo *const[]) {(const NMMetaAbstractInfo *) setting_info, NULL}, fields_str, &error)) return FALSE; return TRUE; } + +const char * +nmc_setting_propname_user_to_libnm(const char *setting_name, const char *prop) +{ + if (NM_IN_STRSET(setting_name, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_SETTING_NAME)) { + if (nm_streq0(prop, "dhcp-send-hostname")) + return NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME_V2; + else if (nm_streq0(prop, "dhcp-send-hostname-deprecated")) + return NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME; + } + + return prop; +} + +const char * +nmc_setting_propname_libnm_to_user(const char *setting_name, const char *prop) +{ + if (NM_IN_STRSET(setting_name, + NM_SETTING_IP4_CONFIG_SETTING_NAME, + NM_SETTING_IP6_CONFIG_SETTING_NAME)) { + if (nm_streq0(prop, NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME_V2)) + return "dhcp-send-hostname"; + else if (nm_streq0(prop, NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME)) + return "dhcp-send-hostname-deprecated"; + } + + return prop; +} diff --git a/src/nmcli/settings.h b/src/nmcli/settings.h index 9cbf13c4..c1d0e387 100644 --- a/src/nmcli/settings.h +++ b/src/nmcli/settings.h @@ -34,4 +34,7 @@ gboolean nmc_setting_set_property(NMClient *client, gboolean setting_details(const NmcConfig *nmc_config, NMSetting *setting, const char *one_prop); +const char *nmc_setting_propname_user_to_libnm(const char *setting_name, const char *prop); +const char *nmc_setting_propname_libnm_to_user(const char *setting_name, const char *prop); + #endif /* NMC_SETTINGS_H */ diff --git a/src/nmcli/utils.c b/src/nmcli/utils.c index c65a5486..a613c28f 100644 --- a/src/nmcli/utils.c +++ b/src/nmcli/utils.c @@ -1016,6 +1016,8 @@ _print_fill(const NmcConfig *nmc_config, PrintDataHeaderCell *header_cell; guint col_idx; const NMMetaAbstractInfo *info; + const char *setting_name; + gboolean is_prop; col = &cols[i_col]; if (!col->is_leaf) @@ -1036,14 +1038,23 @@ _print_fill(const NmcConfig *nmc_config, header_cell->to_print = FALSE; header_cell->title = nm_meta_abstract_info_get_name(info, TRUE); - if (nmc_config->multiline_output && col->parent_col - && NM_IN_SET(info->meta_type, - &nm_meta_type_property_info, - &nmc_meta_type_generic_info)) { - header_cell->title = g_strdup_printf( - "%s.%s", - nm_meta_abstract_info_get_name(col->parent_col->selection_item->info, FALSE), - header_cell->title); + + is_prop = + col->parent_col + && NM_IN_SET(info->meta_type, &nm_meta_type_property_info, &nmc_meta_type_generic_info); + + if (is_prop) { + /* Some properties has different name for the user than internally in + * libnm and D-Bus. Make the conversion from libnm names to user names. + */ + setting_name = + nm_meta_abstract_info_get_name(col->parent_col->selection_item->info, FALSE); + header_cell->title = + nmc_setting_propname_libnm_to_user(setting_name, header_cell->title); + } + + if (nmc_config->multiline_output && is_prop) { + header_cell->title = g_strdup_printf("%s.%s", setting_name, header_cell->title); header_cell->title_to_free = TRUE; } } diff --git a/src/nmcli/utils.h b/src/nmcli/utils.h index b68a3803..b2539bf4 100644 --- a/src/nmcli/utils.h +++ b/src/nmcli/utils.h @@ -269,13 +269,13 @@ struct _NmcMetaGenericInfo { }; #define NMC_META_GENERIC(n, ...) \ - (&((NmcMetaGenericInfo){.meta_type = &nmc_meta_type_generic_info, .name = n, __VA_ARGS__})) + (&((NmcMetaGenericInfo) {.meta_type = &nmc_meta_type_generic_info, .name = n, __VA_ARGS__})) #define NMC_META_GENERIC_WITH_NESTED(n, nest, ...) \ NMC_META_GENERIC(n, .nested = (nest), __VA_ARGS__) #define NMC_META_GENERIC_GROUP(_group_name, _nested, _name_header) \ - ((const NMMetaAbstractInfo *const *) ((const NmcMetaGenericInfo *const[]){ \ + ((const NMMetaAbstractInfo *const *) ((const NmcMetaGenericInfo *const[]) { \ NMC_META_GENERIC_WITH_NESTED(_group_name, _nested, .name_header = _name_header), \ NULL, \ })) diff --git a/src/tests/check-systemd-unit.sh b/src/tests/check-systemd-unit.sh new file mode 100755 index 00000000..b16f2a33 --- /dev/null +++ b/src/tests/check-systemd-unit.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# SPDX-License-Identifier: LGPL-2.1-or-later + +set -e +set -o pipefail + +if systemd-analyze --offline=true security 2>/dev/null </dev/null; then + + # We're using "security" as opposed to "verify" because (as of 2024) + # the latter doesn't support --offline runs. + # + # The point is that if anything appears before the security report + # header, there's an error or a warning while parsing the unit file. + env -i systemd-analyze --offline=true security "$1" 2>&1 |awk ' + /NAME.*DESCRIPTION.*EXPOSURE/ {suppress=1} + {if (!suppress) {print; failed++}} + END {exit failed} + ' + +else + echo "SKIP: systemd-analyze --offline=true security not supported" >&2 +fi diff --git a/src/tests/client/test-client.check-on-disk/test_002.expected b/src/tests/client/test-client.check-on-disk/test_002.expected index 9da93de3..0cfe9634 100644 --- a/src/tests/client/test-client.check-on-disk/test_002.expected +++ b/src/tests/client/test-client.check-on-disk/test_002.expected @@ -502,12 +502,12 @@ NAME UUID TYPE DEVICE con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet -- <<< -size: 1565 +size: 1704 location: src/tests/client/test-client.py:test_002()/23 cmd: $NMCLI c s con-1 lang: C returncode: 0 -stdout: 1437 bytes +stdout: 1576 bytes >>> connection.id: con-1 connection.uuid: 5fcfd6d7-1e63-3332-8826-a7eda103792d @@ -531,6 +531,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -541,12 +544,12 @@ connection.wait-device-timeout: -1 connection.wait-activation-delay: -1 <<< -size: 1576 +size: 1715 location: src/tests/client/test-client.py:test_002()/24 cmd: $NMCLI c s con-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 1438 bytes +stdout: 1577 bytes >>> connection.id: con-1 connection.uuid: 5fcfd6d7-1e63-3332-8826-a7eda103792d @@ -570,6 +573,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) diff --git a/src/tests/client/test-client.check-on-disk/test_003.expected b/src/tests/client/test-client.check-on-disk/test_003.expected index feaed831..3dda2bcf 100644 --- a/src/tests/client/test-client.check-on-disk/test_003.expected +++ b/src/tests/client/test-client.check-on-disk/test_003.expected @@ -182,12 +182,12 @@ id path uuid <<< -size: 5627 +size: 6526 location: src/tests/client/test-client.py:test_003()/14 cmd: $NMCLI con s con-gsm1 lang: C returncode: 0 -stdout: 5494 bytes +stdout: 6393 bytes >>> connection.id: con-gsm1 connection.uuid: UUID-con-gsm1-REPLACED-REPLACED-REPL @@ -211,6 +211,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -232,13 +235,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -247,9 +252,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -263,6 +271,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -278,7 +287,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -304,18 +314,27 @@ gsm.sim-operator-id: -- gsm.mtu: auto gsm.initial-eps-bearer-configure: no gsm.initial-eps-bearer-apn: -- +gsm.initial-eps-bearer-username: -- +gsm.initial-eps-bearer-password: <hidden> +gsm.initial-eps-bearer-password-flags: 0 (none) +gsm.initial-eps-bearer-noauth: yes +gsm.initial-eps-bearer-refuse-eap: no +gsm.initial-eps-bearer-refuse-pap: no +gsm.initial-eps-bearer-refuse-chap: no +gsm.initial-eps-bearer-refuse-mschap: no +gsm.initial-eps-bearer-refuse-mschapv2: no proxy.method: none proxy.browser-only: no proxy.pac-url: -- proxy.pac-script: -- <<< -size: 5665 +size: 6569 location: src/tests/client/test-client.py:test_003()/15 cmd: $NMCLI con s con-gsm1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 5522 bytes +stdout: 6426 bytes >>> connection.id: con-gsm1 connection.uuid: UUID-con-gsm1-REPLACED-REPLACED-REPL @@ -339,6 +358,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -360,13 +382,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -375,9 +399,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -391,6 +418,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -406,7 +434,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -432,48 +461,57 @@ gsm.sim-operator-id: -- gsm.mtu: automatyczne gsm.initial-eps-bearer-configure: nie gsm.initial-eps-bearer-apn: -- +gsm.initial-eps-bearer-username: -- +gsm.initial-eps-bearer-password: <hidden> +gsm.initial-eps-bearer-password-flags: 0 (brak) +gsm.initial-eps-bearer-noauth: tak +gsm.initial-eps-bearer-refuse-eap: nie +gsm.initial-eps-bearer-refuse-pap: nie +gsm.initial-eps-bearer-refuse-chap: nie +gsm.initial-eps-bearer-refuse-mschap: nie +gsm.initial-eps-bearer-refuse-mschapv2: nie proxy.method: none proxy.browser-only: nie proxy.pac-url: -- proxy.pac-script: -- <<< -size: 526 +size: 581 location: src/tests/client/test-client.py:test_003()/16 cmd: $NMCLI -g all con s con-gsm1 lang: C returncode: 0 -stdout: 387 bytes +stdout: 442 bytes >>> -connection:con-gsm1:UUID-con-gsm1-REPLACED-REPLACED-REPL::gsm::no:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::: :0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-gsm1:UUID-con-gsm1-REPLACED-REPLACED-REPL::gsm::no:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::: :0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: serial:5:8:even:1:100 -gsm:no:::<hidden>:0:xyz.con-gsm1::<hidden>:0:no::::auto:no: +gsm:no:::<hidden>:0:xyz.con-gsm1::<hidden>:0:no::::auto:no:::<hidden>:0:yes:no:no:no:no:no proxy:none:no:: <<< -size: 536 +size: 591 location: src/tests/client/test-client.py:test_003()/17 cmd: $NMCLI -g all con s con-gsm1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 387 bytes +stdout: 442 bytes >>> -connection:con-gsm1:UUID-con-gsm1-REPLACED-REPLACED-REPL::gsm::no:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::: :0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-gsm1:UUID-con-gsm1-REPLACED-REPLACED-REPL::gsm::no:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::: :0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: serial:5:8:even:1:100 -gsm:no:::<hidden>:0:xyz.con-gsm1::<hidden>:0:no::::auto:no: +gsm:no:::<hidden>:0:xyz.con-gsm1::<hidden>:0:no::::auto:no:::<hidden>:0:yes:no:no:no:no:no proxy:none:no:: <<< -size: 5615 +size: 6514 location: src/tests/client/test-client.py:test_003()/18 cmd: $NMCLI con s con-gsm2 lang: C returncode: 0 -stdout: 5482 bytes +stdout: 6381 bytes >>> connection.id: con-gsm2 connection.uuid: UUID-con-gsm2-REPLACED-REPLACED-REPL @@ -497,6 +535,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -518,13 +559,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -533,9 +576,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -549,6 +595,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -564,7 +611,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -590,18 +638,27 @@ gsm.sim-operator-id: -- gsm.mtu: auto gsm.initial-eps-bearer-configure: no gsm.initial-eps-bearer-apn: -- +gsm.initial-eps-bearer-username: -- +gsm.initial-eps-bearer-password: <hidden> +gsm.initial-eps-bearer-password-flags: 0 (none) +gsm.initial-eps-bearer-noauth: yes +gsm.initial-eps-bearer-refuse-eap: no +gsm.initial-eps-bearer-refuse-pap: no +gsm.initial-eps-bearer-refuse-chap: no +gsm.initial-eps-bearer-refuse-mschap: no +gsm.initial-eps-bearer-refuse-mschapv2: no proxy.method: none proxy.browser-only: no proxy.pac-url: -- proxy.pac-script: -- <<< -size: 5653 +size: 6557 location: src/tests/client/test-client.py:test_003()/19 cmd: $NMCLI con s con-gsm2 lang: pl_PL.UTF-8 returncode: 0 -stdout: 5510 bytes +stdout: 6414 bytes >>> connection.id: con-gsm2 connection.uuid: UUID-con-gsm2-REPLACED-REPLACED-REPL @@ -625,6 +682,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -646,13 +706,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -661,9 +723,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -677,6 +742,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -692,7 +758,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -718,48 +785,57 @@ gsm.sim-operator-id: -- gsm.mtu: automatyczne gsm.initial-eps-bearer-configure: nie gsm.initial-eps-bearer-apn: -- +gsm.initial-eps-bearer-username: -- +gsm.initial-eps-bearer-password: <hidden> +gsm.initial-eps-bearer-password-flags: 0 (brak) +gsm.initial-eps-bearer-noauth: tak +gsm.initial-eps-bearer-refuse-eap: nie +gsm.initial-eps-bearer-refuse-pap: nie +gsm.initial-eps-bearer-refuse-chap: nie +gsm.initial-eps-bearer-refuse-mschap: nie +gsm.initial-eps-bearer-refuse-mschapv2: nie proxy.method: none proxy.browser-only: nie proxy.pac-url: -- proxy.pac-script: -- <<< -size: 514 +size: 569 location: src/tests/client/test-client.py:test_003()/20 cmd: $NMCLI -g all con s con-gsm2 lang: C returncode: 0 -stdout: 375 bytes +stdout: 430 bytes >>> -connection:con-gsm2:UUID-con-gsm2-REPLACED-REPLACED-REPL::gsm::no:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::: :0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-gsm2:UUID-con-gsm2-REPLACED-REPLACED-REPL::gsm::no:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::: :0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: serial:5:8:even:1:100 -gsm:no:::<hidden>:0:::<hidden>:0:no::::auto:no: +gsm:no:::<hidden>:0:::<hidden>:0:no::::auto:no:::<hidden>:0:yes:no:no:no:no:no proxy:none:no:: <<< -size: 524 +size: 579 location: src/tests/client/test-client.py:test_003()/21 cmd: $NMCLI -g all con s con-gsm2 lang: pl_PL.UTF-8 returncode: 0 -stdout: 375 bytes +stdout: 430 bytes >>> -connection:con-gsm2:UUID-con-gsm2-REPLACED-REPLACED-REPL::gsm::no:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::: :0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-gsm2:UUID-con-gsm2-REPLACED-REPLACED-REPL::gsm::no:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::: :0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: serial:5:8:even:1:100 -gsm:no:::<hidden>:0:::<hidden>:0:no::::auto:no: +gsm:no:::<hidden>:0:::<hidden>:0:no::::auto:no:::<hidden>:0:yes:no:no:no:no:no proxy:none:no:: <<< -size: 5615 +size: 6514 location: src/tests/client/test-client.py:test_003()/22 cmd: $NMCLI con s con-gsm3 lang: C returncode: 0 -stdout: 5482 bytes +stdout: 6381 bytes >>> connection.id: con-gsm3 connection.uuid: UUID-con-gsm3-REPLACED-REPLACED-REPL @@ -783,6 +859,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -804,13 +883,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -819,9 +900,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -835,6 +919,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -850,7 +935,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -876,18 +962,27 @@ gsm.sim-operator-id: -- gsm.mtu: auto gsm.initial-eps-bearer-configure: no gsm.initial-eps-bearer-apn: -- +gsm.initial-eps-bearer-username: -- +gsm.initial-eps-bearer-password: <hidden> +gsm.initial-eps-bearer-password-flags: 0 (none) +gsm.initial-eps-bearer-noauth: yes +gsm.initial-eps-bearer-refuse-eap: no +gsm.initial-eps-bearer-refuse-pap: no +gsm.initial-eps-bearer-refuse-chap: no +gsm.initial-eps-bearer-refuse-mschap: no +gsm.initial-eps-bearer-refuse-mschapv2: no proxy.method: none proxy.browser-only: no proxy.pac-url: -- proxy.pac-script: -- <<< -size: 5653 +size: 6557 location: src/tests/client/test-client.py:test_003()/23 cmd: $NMCLI con s con-gsm3 lang: pl_PL.UTF-8 returncode: 0 -stdout: 5510 bytes +stdout: 6414 bytes >>> connection.id: con-gsm3 connection.uuid: UUID-con-gsm3-REPLACED-REPLACED-REPL @@ -911,6 +1006,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -932,13 +1030,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -947,9 +1047,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -963,6 +1066,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -978,7 +1082,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -1004,39 +1109,48 @@ gsm.sim-operator-id: -- gsm.mtu: automatyczne gsm.initial-eps-bearer-configure: nie gsm.initial-eps-bearer-apn: -- +gsm.initial-eps-bearer-username: -- +gsm.initial-eps-bearer-password: <hidden> +gsm.initial-eps-bearer-password-flags: 0 (brak) +gsm.initial-eps-bearer-noauth: tak +gsm.initial-eps-bearer-refuse-eap: nie +gsm.initial-eps-bearer-refuse-pap: nie +gsm.initial-eps-bearer-refuse-chap: nie +gsm.initial-eps-bearer-refuse-mschap: nie +gsm.initial-eps-bearer-refuse-mschapv2: nie proxy.method: none proxy.browser-only: nie proxy.pac-url: -- proxy.pac-script: -- <<< -size: 515 +size: 570 location: src/tests/client/test-client.py:test_003()/24 cmd: $NMCLI -g all con s con-gsm3 lang: C returncode: 0 -stdout: 376 bytes +stdout: 431 bytes >>> -connection:con-gsm3:UUID-con-gsm3-REPLACED-REPLACED-REPL::gsm::no:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::: :0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-gsm3:UUID-con-gsm3-REPLACED-REPLACED-REPL::gsm::no:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::: :0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: serial:5:8:even:1:100 -gsm:no:::<hidden>:0: ::<hidden>:0:no::::auto:no: +gsm:no:::<hidden>:0: ::<hidden>:0:no::::auto:no:::<hidden>:0:yes:no:no:no:no:no proxy:none:no:: <<< -size: 525 +size: 580 location: src/tests/client/test-client.py:test_003()/25 cmd: $NMCLI -g all con s con-gsm3 lang: pl_PL.UTF-8 returncode: 0 -stdout: 376 bytes +stdout: 431 bytes >>> -connection:con-gsm3:UUID-con-gsm3-REPLACED-REPLACED-REPL::gsm::no:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::: :0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-gsm3:UUID-con-gsm3-REPLACED-REPLACED-REPL::gsm::no:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::: :0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: serial:5:8:even:1:100 -gsm:no:::<hidden>:0: ::<hidden>:0:no::::auto:no: +gsm:no:::<hidden>:0: ::<hidden>:0:no::::auto:no:::<hidden>:0:yes:no:no:no:no:no proxy:none:no:: <<< @@ -1180,12 +1294,12 @@ UUID NAME UUID-ethernet-REPLACED-REPLACED-REPL ethernet <<< -size: 5367 +size: 5866 location: src/tests/client/test-client.py:test_003()/37 cmd: $NMCLI -f ALL con s ethernet lang: C returncode: 0 -stdout: 5227 bytes +stdout: 5726 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -1209,6 +1323,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -1245,13 +1362,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -1260,9 +1379,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -1276,6 +1398,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -1291,7 +1414,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -1302,12 +1426,12 @@ proxy.pac-url: -- proxy.pac-script: -- <<< -size: 5402 +size: 5901 location: src/tests/client/test-client.py:test_003()/38 cmd: $NMCLI -f ALL con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 5252 bytes +stdout: 5751 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -1331,6 +1455,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -1367,13 +1494,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -1382,9 +1511,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -1398,6 +1530,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -1413,7 +1546,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -1444,12 +1578,12 @@ stdout: 51 bytes GENERAL.STATE: aktywowano <<< -size: 6069 +size: 6568 location: src/tests/client/test-client.py:test_003()/41 cmd: $NMCLI con s ethernet lang: C returncode: 0 -stdout: 5936 bytes +stdout: 6435 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -1473,6 +1607,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -1509,13 +1646,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -1524,9 +1663,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -1540,6 +1682,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -1555,7 +1698,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -1579,12 +1723,12 @@ GENERAL.ZONE: -- GENERAL.MASTER-PATH: -- <<< -size: 6108 +size: 6607 location: src/tests/client/test-client.py:test_003()/42 cmd: $NMCLI con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 5965 bytes +stdout: 6464 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -1608,6 +1752,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -1644,13 +1791,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -1659,9 +1808,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -1675,6 +1827,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -1690,7 +1843,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -2200,12 +2354,12 @@ UUID NAME UUID-ethernet-REPLACED-REPLACED-REPL ethernet <<< -size: 5367 +size: 5866 location: src/tests/client/test-client.py:test_003()/62 cmd: $NMCLI -f ALL con s ethernet lang: C returncode: 0 -stdout: 5227 bytes +stdout: 5726 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -2229,6 +2383,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -2265,13 +2422,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -2280,9 +2439,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -2296,6 +2458,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -2311,7 +2474,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -2322,12 +2486,12 @@ proxy.pac-url: -- proxy.pac-script: -- <<< -size: 5402 +size: 5901 location: src/tests/client/test-client.py:test_003()/63 cmd: $NMCLI -f ALL con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 5252 bytes +stdout: 5751 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -2351,6 +2515,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -2387,13 +2554,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -2402,9 +2571,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -2418,6 +2590,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -2433,7 +2606,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -2468,12 +2642,12 @@ GENERAL.STATE: aktywowano GENERAL.STATE: aktywowano <<< -size: 6779 +size: 7278 location: src/tests/client/test-client.py:test_003()/66 cmd: $NMCLI con s ethernet lang: C returncode: 0 -stdout: 6646 bytes +stdout: 7145 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -2497,6 +2671,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -2533,13 +2710,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -2548,9 +2727,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -2564,6 +2746,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -2579,7 +2762,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -2617,12 +2801,12 @@ GENERAL.ZONE: -- GENERAL.MASTER-PATH: -- <<< -size: 6822 +size: 7321 location: src/tests/client/test-client.py:test_003()/67 cmd: $NMCLI con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 6679 bytes +stdout: 7178 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -2646,6 +2830,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -2682,13 +2869,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -2697,9 +2886,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -2713,6 +2905,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -2728,7 +2921,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -3274,12 +3468,12 @@ UUID-con-gsm3-REPLACED-REPLACED-REPL gsm UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet <<< -size: 6782 +size: 7281 location: src/tests/client/test-client.py:test_003()/84 cmd: $NMCLI con s ethernet lang: C returncode: 0 -stdout: 6649 bytes +stdout: 7148 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -3303,6 +3497,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -3339,13 +3536,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -3354,9 +3553,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -3370,6 +3572,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -3385,7 +3588,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -3423,12 +3627,12 @@ GENERAL.ZONE: -- GENERAL.MASTER-PATH: -- <<< -size: 6826 +size: 7325 location: src/tests/client/test-client.py:test_003()/85 cmd: $NMCLI con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 6683 bytes +stdout: 7182 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -3452,6 +3656,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -3488,13 +3695,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -3503,9 +3712,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -3519,6 +3731,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -3534,7 +3747,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -3572,12 +3786,12 @@ GENERAL.ZONE: -- GENERAL.MASTER-PATH: -- <<< -size: 6112 +size: 6611 location: src/tests/client/test-client.py:test_003()/86 cmd: $NMCLI c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 5939 bytes +stdout: 6438 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -3601,6 +3815,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -3637,13 +3854,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -3652,9 +3871,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -3668,6 +3890,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -3683,7 +3906,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -3707,12 +3931,12 @@ GENERAL.ZONE: -- GENERAL.MASTER-PATH: -- <<< -size: 6152 +size: 6651 location: src/tests/client/test-client.py:test_003()/87 cmd: $NMCLI c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 5969 bytes +stdout: 6468 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -3736,6 +3960,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -3772,13 +3999,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -3787,9 +4016,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -3803,6 +4035,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -3818,7 +4051,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -4052,12 +4286,12 @@ UUID-con-gsm3-REPLACED-REPLACED-REPL gsm UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet <<< -size: 6794 +size: 7293 location: src/tests/client/test-client.py:test_003()/94 cmd: $NMCLI --color yes con s ethernet lang: C returncode: 0 -stdout: 6649 bytes +stdout: 7148 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -4081,6 +4315,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -4117,13 +4354,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -4132,9 +4371,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -4148,6 +4390,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -4163,7 +4406,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -4201,12 +4445,12 @@ GENERAL.ZONE: -- GENERAL.MASTER-PATH: -- <<< -size: 6838 +size: 7337 location: src/tests/client/test-client.py:test_003()/95 cmd: $NMCLI --color yes con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 6683 bytes +stdout: 7182 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -4230,6 +4474,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -4266,13 +4513,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -4281,9 +4530,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -4297,6 +4549,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -4312,7 +4565,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -4350,12 +4604,12 @@ GENERAL.ZONE: -- GENERAL.MASTER-PATH: -- <<< -size: 6124 +size: 6623 location: src/tests/client/test-client.py:test_003()/96 cmd: $NMCLI --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 5939 bytes +stdout: 6438 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -4379,6 +4633,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -4415,13 +4672,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -4430,9 +4689,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -4446,6 +4708,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -4461,7 +4724,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -4485,12 +4749,12 @@ GENERAL.ZONE: -- GENERAL.MASTER-PATH: -- <<< -size: 6164 +size: 6663 location: src/tests/client/test-client.py:test_003()/97 cmd: $NMCLI --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 5969 bytes +stdout: 6468 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -4514,6 +4778,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -4550,13 +4817,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -4565,9 +4834,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -4581,6 +4853,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -4596,7 +4869,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -4846,12 +5120,12 @@ UUID-con-gsm3-REPLACED-REPLACED-REPL gsm UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet <<< -size: 8035 +size: 8534 location: src/tests/client/test-client.py:test_003()/104 cmd: $NMCLI --pretty con s ethernet lang: C returncode: 0 -stdout: 7892 bytes +stdout: 8391 bytes >>> =============================================================================== Connection profile details (ethernet) @@ -4878,6 +5152,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -4916,13 +5193,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -4931,9 +5210,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -4948,6 +5230,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -4963,7 +5246,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -5011,12 +5295,12 @@ GENERAL.MASTER-PATH: -- ------------------------------------------------------------------------------- <<< -size: 8100 +size: 8599 location: src/tests/client/test-client.py:test_003()/105 cmd: $NMCLI --pretty con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 7947 bytes +stdout: 8446 bytes >>> =============================================================================== Szczegóły profilu połączenia (ethernet) @@ -5043,6 +5327,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -5081,13 +5368,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -5096,9 +5385,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -5113,6 +5405,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -5128,7 +5421,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -5176,12 +5470,12 @@ GENERAL.MASTER-PATH: -- ------------------------------------------------------------------------------- <<< -size: 7053 +size: 7552 location: src/tests/client/test-client.py:test_003()/106 cmd: $NMCLI --pretty c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 6870 bytes +stdout: 7369 bytes >>> =============================================================================== Connection profile details (ethernet) @@ -5208,6 +5502,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -5246,13 +5543,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -5261,9 +5560,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -5278,6 +5580,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -5293,7 +5596,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -5323,12 +5627,12 @@ GENERAL.MASTER-PATH: -- ------------------------------------------------------------------------------- <<< -size: 7106 +size: 7605 location: src/tests/client/test-client.py:test_003()/107 cmd: $NMCLI --pretty c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6913 bytes +stdout: 7412 bytes >>> =============================================================================== Szczegóły profilu połączenia (ethernet) @@ -5355,6 +5659,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -5393,13 +5700,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -5408,9 +5717,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -5425,6 +5737,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -5440,7 +5753,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -5720,12 +6034,12 @@ UUID-con-gsm3-REPLACED-REPLACED-REPL gsm UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet <<< -size: 8047 +size: 8546 location: src/tests/client/test-client.py:test_003()/114 cmd: $NMCLI --pretty --color yes con s ethernet lang: C returncode: 0 -stdout: 7892 bytes +stdout: 8391 bytes >>> =============================================================================== Connection profile details (ethernet) @@ -5752,6 +6066,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -5790,13 +6107,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -5805,9 +6124,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -5822,6 +6144,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -5837,7 +6160,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -5885,12 +6209,12 @@ GENERAL.MASTER-PATH: -- ------------------------------------------------------------------------------- <<< -size: 8112 +size: 8611 location: src/tests/client/test-client.py:test_003()/115 cmd: $NMCLI --pretty --color yes con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 7947 bytes +stdout: 8446 bytes >>> =============================================================================== Szczegóły profilu połączenia (ethernet) @@ -5917,6 +6241,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -5955,13 +6282,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -5970,9 +6299,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -5987,6 +6319,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -6002,7 +6335,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -6050,12 +6384,12 @@ GENERAL.MASTER-PATH: -- ------------------------------------------------------------------------------- <<< -size: 7065 +size: 7564 location: src/tests/client/test-client.py:test_003()/116 cmd: $NMCLI --pretty --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 6870 bytes +stdout: 7369 bytes >>> =============================================================================== Connection profile details (ethernet) @@ -6082,6 +6416,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -6120,13 +6457,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -6135,9 +6474,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -6152,6 +6494,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -6167,7 +6510,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -6197,12 +6541,12 @@ GENERAL.MASTER-PATH: -- ------------------------------------------------------------------------------- <<< -size: 7118 +size: 7617 location: src/tests/client/test-client.py:test_003()/117 cmd: $NMCLI --pretty --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6913 bytes +stdout: 7412 bytes >>> =============================================================================== Szczegóły profilu połączenia (ethernet) @@ -6229,6 +6573,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -6267,13 +6614,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -6282,9 +6631,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -6299,6 +6651,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -6314,7 +6667,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -6574,12 +6928,12 @@ UUID-con-gsm3-REPLACED-REPLACED-REPL:gsm UUID-con-xx1-REPLACED-REPLACED-REPLA:802-3-ethernet <<< -size: 3615 +size: 3919 location: src/tests/client/test-client.py:test_003()/124 cmd: $NMCLI --terse con s ethernet lang: C returncode: 0 -stdout: 3473 bytes +stdout: 3777 bytes >>> connection.id:ethernet connection.uuid:UUID-ethernet-REPLACED-REPLACED-REPL @@ -6603,6 +6957,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -6639,13 +6996,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -6654,9 +7013,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -6670,6 +7032,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -6685,7 +7048,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -6723,12 +7087,12 @@ GENERAL.ZONE: GENERAL.MASTER-PATH: <<< -size: 3625 +size: 3929 location: src/tests/client/test-client.py:test_003()/125 cmd: $NMCLI --terse con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 3473 bytes +stdout: 3777 bytes >>> connection.id:ethernet connection.uuid:UUID-ethernet-REPLACED-REPLACED-REPL @@ -6752,6 +7116,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -6788,13 +7155,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -6803,9 +7172,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -6819,6 +7191,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -6834,7 +7207,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -6872,12 +7246,12 @@ GENERAL.ZONE: GENERAL.MASTER-PATH: <<< -size: 3265 +size: 3569 location: src/tests/client/test-client.py:test_003()/126 cmd: $NMCLI --terse c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 3083 bytes +stdout: 3387 bytes >>> connection.id:ethernet connection.uuid:UUID-ethernet-REPLACED-REPLACED-REPL @@ -6901,6 +7275,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -6937,13 +7314,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -6952,9 +7331,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -6968,6 +7350,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -6983,7 +7366,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -7007,12 +7391,12 @@ GENERAL.ZONE: GENERAL.MASTER-PATH: <<< -size: 3275 +size: 3579 location: src/tests/client/test-client.py:test_003()/127 cmd: $NMCLI --terse c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 3083 bytes +stdout: 3387 bytes >>> connection.id:ethernet connection.uuid:UUID-ethernet-REPLACED-REPLACED-REPL @@ -7036,6 +7420,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -7072,13 +7459,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -7087,9 +7476,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -7103,6 +7495,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -7118,7 +7511,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -7348,12 +7742,12 @@ UUID-con-gsm3-REPLACED-REPLACED-REPL:gsm UUID-con-xx1-REPLACED-REPLACED-REPLA:802-3-ethernet <<< -size: 3627 +size: 3931 location: src/tests/client/test-client.py:test_003()/134 cmd: $NMCLI --terse --color yes con s ethernet lang: C returncode: 0 -stdout: 3473 bytes +stdout: 3777 bytes >>> connection.id:ethernet connection.uuid:UUID-ethernet-REPLACED-REPLACED-REPL @@ -7377,6 +7771,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -7413,13 +7810,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -7428,9 +7827,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -7444,6 +7846,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -7459,7 +7862,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -7497,12 +7901,12 @@ GENERAL.ZONE: GENERAL.MASTER-PATH: <<< -size: 3637 +size: 3941 location: src/tests/client/test-client.py:test_003()/135 cmd: $NMCLI --terse --color yes con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 3473 bytes +stdout: 3777 bytes >>> connection.id:ethernet connection.uuid:UUID-ethernet-REPLACED-REPLACED-REPL @@ -7526,6 +7930,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -7562,13 +7969,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -7577,9 +7986,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -7593,6 +8005,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -7608,7 +8021,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -7646,12 +8060,12 @@ GENERAL.ZONE: GENERAL.MASTER-PATH: <<< -size: 3277 +size: 3581 location: src/tests/client/test-client.py:test_003()/136 cmd: $NMCLI --terse --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 3083 bytes +stdout: 3387 bytes >>> connection.id:ethernet connection.uuid:UUID-ethernet-REPLACED-REPLACED-REPL @@ -7675,6 +8089,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -7711,13 +8128,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -7726,9 +8145,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -7742,6 +8164,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -7757,7 +8180,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -7781,12 +8205,12 @@ GENERAL.ZONE: GENERAL.MASTER-PATH: <<< -size: 3287 +size: 3591 location: src/tests/client/test-client.py:test_003()/137 cmd: $NMCLI --terse --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 3083 bytes +stdout: 3387 bytes >>> connection.id:ethernet connection.uuid:UUID-ethernet-REPLACED-REPLACED-REPL @@ -7810,6 +8234,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -7846,13 +8273,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -7861,9 +8290,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -7877,6 +8309,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -7892,7 +8325,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -8126,24 +8560,24 @@ UUID-con-gsm3-REPLACED-REPLACED-REPL gsm UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet <<< -size: 4575 +size: 5027 location: src/tests/client/test-client.py:test_003()/144 cmd: $NMCLI --mode tabular con s ethernet lang: C returncode: 0 -stdout: 4426 bytes +stdout: 4878 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 name port speed duplex auto-negotiate mac-address cloned-mac-address generate-mac-address-mask mac-address-denylist mtu s390-subchannels s390-nettype s390-options wake-on-lan wake-on-lan-password accept-all-mac-addresses 802-3-ethernet -- 0 -- no -- -- -- -- auto -- -- -- default -- -1 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name method browser-only pac-url pac-script proxy none no -- -- @@ -8157,24 +8591,24 @@ GENERAL ethernet UUID-ethernet-REPLACED-REPLACED-REPL eth0 eth0 deac <<< -size: 4625 +size: 5077 location: src/tests/client/test-client.py:test_003()/145 cmd: $NMCLI --mode tabular con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 4466 bytes +stdout: 4918 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 name port speed duplex auto-negotiate mac-address cloned-mac-address generate-mac-address-mask mac-address-denylist mtu s390-subchannels s390-nettype s390-options wake-on-lan wake-on-lan-password accept-all-mac-addresses 802-3-ethernet -- 0 -- nie -- -- -- -- automatyczne -- -- -- default -- -1 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name method browser-only pac-url pac-script proxy none nie -- -- @@ -8188,24 +8622,24 @@ GENERAL ethernet UUID-ethernet-REPLACED-REPLACED-REPL eth0 eth0 deza <<< -size: 4113 +size: 4565 location: src/tests/client/test-client.py:test_003()/146 cmd: $NMCLI --mode tabular c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 3924 bytes +stdout: 4376 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 name port speed duplex auto-negotiate mac-address cloned-mac-address generate-mac-address-mask mac-address-denylist mtu s390-subchannels s390-nettype s390-options wake-on-lan wake-on-lan-password accept-all-mac-addresses 802-3-ethernet -- 0 -- no -- -- -- -- auto -- -- -- default -- -1 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name method browser-only pac-url pac-script proxy none no -- -- @@ -8215,24 +8649,24 @@ GENERAL ethernet UUID-ethernet-REPLACED-REPLACED-REPL eth0 eth0 deac <<< -size: 4161 +size: 4613 location: src/tests/client/test-client.py:test_003()/147 cmd: $NMCLI --mode tabular c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 3962 bytes +stdout: 4414 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 name port speed duplex auto-negotiate mac-address cloned-mac-address generate-mac-address-mask mac-address-denylist mtu s390-subchannels s390-nettype s390-options wake-on-lan wake-on-lan-password accept-all-mac-addresses 802-3-ethernet -- 0 -- nie -- -- -- -- automatyczne -- -- -- default -- -1 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name method browser-only pac-url pac-script proxy none nie -- -- @@ -8378,24 +8812,24 @@ UUID-con-gsm3-REPLACED-REPLACED-REPL gsm UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet <<< -size: 4587 +size: 5039 location: src/tests/client/test-client.py:test_003()/154 cmd: $NMCLI --mode tabular --color yes con s ethernet lang: C returncode: 0 -stdout: 4426 bytes +stdout: 4878 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 name port speed duplex auto-negotiate mac-address cloned-mac-address generate-mac-address-mask mac-address-denylist mtu s390-subchannels s390-nettype s390-options wake-on-lan wake-on-lan-password accept-all-mac-addresses 802-3-ethernet -- 0 -- no -- -- -- -- auto -- -- -- default -- -1 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name method browser-only pac-url pac-script proxy none no -- -- @@ -8409,24 +8843,24 @@ GENERAL ethernet UUID-ethernet-REPLACED-REPLACED-REPL eth0 eth0 deac <<< -size: 4637 +size: 5089 location: src/tests/client/test-client.py:test_003()/155 cmd: $NMCLI --mode tabular --color yes con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 4466 bytes +stdout: 4918 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 name port speed duplex auto-negotiate mac-address cloned-mac-address generate-mac-address-mask mac-address-denylist mtu s390-subchannels s390-nettype s390-options wake-on-lan wake-on-lan-password accept-all-mac-addresses 802-3-ethernet -- 0 -- nie -- -- -- -- automatyczne -- -- -- default -- -1 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name method browser-only pac-url pac-script proxy none nie -- -- @@ -8440,24 +8874,24 @@ GENERAL ethernet UUID-ethernet-REPLACED-REPLACED-REPL eth0 eth0 deza <<< -size: 4125 +size: 4577 location: src/tests/client/test-client.py:test_003()/156 cmd: $NMCLI --mode tabular --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 3924 bytes +stdout: 4376 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 name port speed duplex auto-negotiate mac-address cloned-mac-address generate-mac-address-mask mac-address-denylist mtu s390-subchannels s390-nettype s390-options wake-on-lan wake-on-lan-password accept-all-mac-addresses 802-3-ethernet -- 0 -- no -- -- -- -- auto -- -- -- default -- -1 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name method browser-only pac-url pac-script proxy none no -- -- @@ -8467,24 +8901,24 @@ GENERAL ethernet UUID-ethernet-REPLACED-REPLACED-REPL eth0 eth0 deac <<< -size: 4173 +size: 4625 location: src/tests/client/test-client.py:test_003()/157 cmd: $NMCLI --mode tabular --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 3962 bytes +stdout: 4414 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 name port speed duplex auto-negotiate mac-address cloned-mac-address generate-mac-address-mask mac-address-denylist mtu s390-subchannels s390-nettype s390-options wake-on-lan wake-on-lan-password accept-all-mac-addresses 802-3-ethernet -- 0 -- nie -- -- -- -- automatyczne -- -- -- default -- -1 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name method browser-only pac-url pac-script proxy none nie -- -- @@ -8646,31 +9080,31 @@ UUID-con-gsm3-REPLACED-REPLACED-REPL gsm UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet <<< -size: 7334 +size: 8012 location: src/tests/client/test-client.py:test_003()/164 cmd: $NMCLI --mode tabular --pretty con s ethernet lang: C returncode: 0 -stdout: 7176 bytes +stdout: 7854 bytes >>> ========================================= Connection profile details (ethernet) ========================================= -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 name port speed duplex auto-negotiate mac-address cloned-mac-address generate-mac-address-mask mac-address-denylist mtu s390-subchannels s390-nettype s390-options wake-on-lan wake-on-lan-password accept-all-mac-addresses -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 802-3-ethernet -- 0 -- no -- -- -- -- auto -- -- -- default -- -1 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name method browser-only pac-url pac-script -------------------------------------------------- @@ -8693,31 +9127,31 @@ GENERAL ethernet UUID-ethernet-REPLACED-REPLACED-REPL eth0 eth0 deac <<< -size: 7464 +size: 8142 location: src/tests/client/test-client.py:test_003()/165 cmd: $NMCLI --mode tabular --pretty con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 7296 bytes +stdout: 7974 bytes >>> =========================================== Szczegóły profilu połączenia (ethernet) =========================================== -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 name port speed duplex auto-negotiate mac-address cloned-mac-address generate-mac-address-mask mac-address-denylist mtu s390-subchannels s390-nettype s390-options wake-on-lan wake-on-lan-password accept-all-mac-addresses ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 802-3-ethernet -- 0 -- nie -- -- -- -- automatyczne -- -- -- default -- -1 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name method browser-only pac-url pac-script -------------------------------------------------- @@ -8740,31 +9174,31 @@ GENERAL ethernet UUID-ethernet-REPLACED-REPLACED-REPL eth0 eth0 deza <<< -size: 6416 +size: 7094 location: src/tests/client/test-client.py:test_003()/166 cmd: $NMCLI --mode tabular --pretty c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 6218 bytes +stdout: 6896 bytes >>> ========================================= Connection profile details (ethernet) ========================================= -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 name port speed duplex auto-negotiate mac-address cloned-mac-address generate-mac-address-mask mac-address-denylist mtu s390-subchannels s390-nettype s390-options wake-on-lan wake-on-lan-password accept-all-mac-addresses -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 802-3-ethernet -- 0 -- no -- -- -- -- auto -- -- -- default -- -1 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name method browser-only pac-url pac-script -------------------------------------------------- @@ -8779,31 +9213,31 @@ GENERAL ethernet UUID-ethernet-REPLACED-REPLACED-REPL eth0 eth0 deac <<< -size: 6518 +size: 7196 location: src/tests/client/test-client.py:test_003()/167 cmd: $NMCLI --mode tabular --pretty c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6310 bytes +stdout: 6988 bytes >>> =========================================== Szczegóły profilu połączenia (ethernet) =========================================== -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 name port speed duplex auto-negotiate mac-address cloned-mac-address generate-mac-address-mask mac-address-denylist mtu s390-subchannels s390-nettype s390-options wake-on-lan wake-on-lan-password accept-all-mac-addresses ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 802-3-ethernet -- 0 -- nie -- -- -- -- automatyczne -- -- -- default -- -1 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name method browser-only pac-url pac-script -------------------------------------------------- @@ -8994,31 +9428,31 @@ UUID-con-gsm3-REPLACED-REPLACED-REPL gsm UUID-con-xx1-REPLACED-REPLACED-REPLA ethernet <<< -size: 7346 +size: 8024 location: src/tests/client/test-client.py:test_003()/174 cmd: $NMCLI --mode tabular --pretty --color yes con s ethernet lang: C returncode: 0 -stdout: 7176 bytes +stdout: 7854 bytes >>> ========================================= Connection profile details (ethernet) ========================================= -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 name port speed duplex auto-negotiate mac-address cloned-mac-address generate-mac-address-mask mac-address-denylist mtu s390-subchannels s390-nettype s390-options wake-on-lan wake-on-lan-password accept-all-mac-addresses -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 802-3-ethernet -- 0 -- no -- -- -- -- auto -- -- -- default -- -1 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name method browser-only pac-url pac-script -------------------------------------------------- @@ -9041,31 +9475,31 @@ GENERAL ethernet UUID-ethernet-REPLACED-REPLACED-REPL eth0 eth0 deac <<< -size: 7476 +size: 8154 location: src/tests/client/test-client.py:test_003()/175 cmd: $NMCLI --mode tabular --pretty --color yes con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 7296 bytes +stdout: 7974 bytes >>> =========================================== Szczegóły profilu połączenia (ethernet) =========================================== -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 name port speed duplex auto-negotiate mac-address cloned-mac-address generate-mac-address-mask mac-address-denylist mtu s390-subchannels s390-nettype s390-options wake-on-lan wake-on-lan-password accept-all-mac-addresses ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 802-3-ethernet -- 0 -- nie -- -- -- -- automatyczne -- -- -- default -- -1 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name method browser-only pac-url pac-script -------------------------------------------------- @@ -9088,31 +9522,31 @@ GENERAL ethernet UUID-ethernet-REPLACED-REPLACED-REPL eth0 eth0 deza <<< -size: 6428 +size: 7106 location: src/tests/client/test-client.py:test_003()/176 cmd: $NMCLI --mode tabular --pretty --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 6218 bytes +stdout: 6896 bytes >>> ========================================= Connection profile details (ethernet) ========================================= -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 name port speed duplex auto-negotiate mac-address cloned-mac-address generate-mac-address-mask mac-address-denylist mtu s390-subchannels s390-nettype s390-options wake-on-lan wake-on-lan-password accept-all-mac-addresses -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 802-3-ethernet -- 0 -- no -- -- -- -- auto -- -- -- default -- -1 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name method browser-only pac-url pac-script -------------------------------------------------- @@ -9127,31 +9561,31 @@ GENERAL ethernet UUID-ethernet-REPLACED-REPLACED-REPL eth0 eth0 deac <<< -size: 6530 +size: 7208 location: src/tests/client/test-client.py:test_003()/177 cmd: $NMCLI --mode tabular --pretty --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6310 bytes +stdout: 6988 bytes >>> =========================================== Szczegóły profilu połączenia (ethernet) =========================================== -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +connection ethernet UUID-ethernet-REPLACED-REPLACED-REPL -- 802-3-ethernet -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 name port speed duplex auto-negotiate mac-address cloned-mac-address generate-mac-address-mask mac-address-denylist mtu s390-subchannels s390-nettype s390-options wake-on-lan wake-on-lan-password accept-all-mac-addresses ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 802-3-ethernet -- 0 -- nie -- -- -- -- automatyczne -- -- -- default -- -1 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name method browser-only pac-url pac-script -------------------------------------------------- @@ -9322,66 +9756,66 @@ UUID-con-gsm3-REPLACED-REPLACED-REPL:gsm UUID-con-xx1-REPLACED-REPLACED-REPLA:802-3-ethernet <<< -size: 904 +size: 928 location: src/tests/client/test-client.py:test_003()/184 cmd: $NMCLI --mode tabular --terse con s ethernet lang: C returncode: 0 -stdout: 748 bytes +stdout: 772 bytes >>> -connection:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL::802-3-ethernet::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 +connection:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL::802-3-ethernet::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 802-3-ethernet::0::no:::::auto::::default::-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: proxy:none:no:: GENERAL:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL:eth1:eth1:activated:no:no::no:/org/freedesktop/NetworkManager/ActiveConnection/2:/org/freedesktop/NetworkManager/Settings/Connection/6:: GENERAL:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL:eth0:eth0:deactivating:no:no::no:/org/freedesktop/NetworkManager/ActiveConnection/1:/org/freedesktop/NetworkManager/Settings/Connection/6:: <<< -size: 914 +size: 938 location: src/tests/client/test-client.py:test_003()/185 cmd: $NMCLI --mode tabular --terse con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 748 bytes +stdout: 772 bytes >>> -connection:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL::802-3-ethernet::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 +connection:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL::802-3-ethernet::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 802-3-ethernet::0::no:::::auto::::default::-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: proxy:none:no:: GENERAL:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL:eth1:eth1:activated:no:no::no:/org/freedesktop/NetworkManager/ActiveConnection/2:/org/freedesktop/NetworkManager/Settings/Connection/6:: GENERAL:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL:eth0:eth0:deactivating:no:no::no:/org/freedesktop/NetworkManager/ActiveConnection/1:/org/freedesktop/NetworkManager/Settings/Connection/6:: <<< -size: 752 +size: 776 location: src/tests/client/test-client.py:test_003()/186 cmd: $NMCLI --mode tabular --terse c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 556 bytes +stdout: 580 bytes >>> -connection:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL::802-3-ethernet::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 +connection:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL::802-3-ethernet::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 802-3-ethernet::0::no:::::auto::::default::-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: proxy:none:no:: GENERAL:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL:eth0:eth0:deactivating:no:no::no:/org/freedesktop/NetworkManager/ActiveConnection/1:/org/freedesktop/NetworkManager/Settings/Connection/6:: <<< -size: 762 +size: 786 location: src/tests/client/test-client.py:test_003()/187 cmd: $NMCLI --mode tabular --terse c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 556 bytes +stdout: 580 bytes >>> -connection:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL::802-3-ethernet::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 +connection:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL::802-3-ethernet::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 802-3-ethernet::0::no:::::auto::::default::-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: proxy:none:no:: GENERAL:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL:eth0:eth0:deactivating:no:no::no:/org/freedesktop/NetworkManager/ActiveConnection/1:/org/freedesktop/NetworkManager/Settings/Connection/6:: @@ -9484,66 +9918,66 @@ UUID-con-gsm3-REPLACED-REPLACED-REPL:gsm UUID-con-xx1-REPLACED-REPLACED-REPLA:802-3-ethernet <<< -size: 916 +size: 940 location: src/tests/client/test-client.py:test_003()/194 cmd: $NMCLI --mode tabular --terse --color yes con s ethernet lang: C returncode: 0 -stdout: 748 bytes +stdout: 772 bytes >>> -connection:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL::802-3-ethernet::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 +connection:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL::802-3-ethernet::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 802-3-ethernet::0::no:::::auto::::default::-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: proxy:none:no:: GENERAL:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL:eth1:eth1:activated:no:no::no:/org/freedesktop/NetworkManager/ActiveConnection/2:/org/freedesktop/NetworkManager/Settings/Connection/6:: GENERAL:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL:eth0:eth0:deactivating:no:no::no:/org/freedesktop/NetworkManager/ActiveConnection/1:/org/freedesktop/NetworkManager/Settings/Connection/6:: <<< -size: 926 +size: 950 location: src/tests/client/test-client.py:test_003()/195 cmd: $NMCLI --mode tabular --terse --color yes con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 748 bytes +stdout: 772 bytes >>> -connection:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL::802-3-ethernet::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 +connection:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL::802-3-ethernet::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 802-3-ethernet::0::no:::::auto::::default::-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: proxy:none:no:: GENERAL:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL:eth1:eth1:activated:no:no::no:/org/freedesktop/NetworkManager/ActiveConnection/2:/org/freedesktop/NetworkManager/Settings/Connection/6:: GENERAL:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL:eth0:eth0:deactivating:no:no::no:/org/freedesktop/NetworkManager/ActiveConnection/1:/org/freedesktop/NetworkManager/Settings/Connection/6:: <<< -size: 764 +size: 788 location: src/tests/client/test-client.py:test_003()/196 cmd: $NMCLI --mode tabular --terse --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 556 bytes +stdout: 580 bytes >>> -connection:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL::802-3-ethernet::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 +connection:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL::802-3-ethernet::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 802-3-ethernet::0::no:::::auto::::default::-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: proxy:none:no:: GENERAL:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL:eth0:eth0:deactivating:no:no::no:/org/freedesktop/NetworkManager/ActiveConnection/1:/org/freedesktop/NetworkManager/Settings/Connection/6:: <<< -size: 774 +size: 798 location: src/tests/client/test-client.py:test_003()/197 cmd: $NMCLI --mode tabular --terse --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 556 bytes +stdout: 580 bytes >>> -connection:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL::802-3-ethernet::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 +connection:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL::802-3-ethernet::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 802-3-ethernet::0::no:::::auto::::default::-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: proxy:none:no:: GENERAL:ethernet:UUID-ethernet-REPLACED-REPLACED-REPL:eth0:eth0:deactivating:no:no::no:/org/freedesktop/NetworkManager/ActiveConnection/1:/org/freedesktop/NetworkManager/Settings/Connection/6:: @@ -9854,12 +10288,12 @@ UUID: UUID-con-xx1-REPLACED-REPLACED-REPLA TYPE: ethernet <<< -size: 6800 +size: 7299 location: src/tests/client/test-client.py:test_003()/204 cmd: $NMCLI --mode multiline con s ethernet lang: C returncode: 0 -stdout: 6649 bytes +stdout: 7148 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -9883,6 +10317,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -9919,13 +10356,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -9934,9 +10373,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -9950,6 +10392,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -9965,7 +10408,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -10003,12 +10447,12 @@ GENERAL.ZONE: -- GENERAL.MASTER-PATH: -- <<< -size: 6844 +size: 7343 location: src/tests/client/test-client.py:test_003()/205 cmd: $NMCLI --mode multiline con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 6683 bytes +stdout: 7182 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -10032,6 +10476,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -10068,13 +10515,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -10083,9 +10532,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -10099,6 +10551,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -10114,7 +10567,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -10152,12 +10606,12 @@ GENERAL.ZONE: -- GENERAL.MASTER-PATH: -- <<< -size: 6130 +size: 6629 location: src/tests/client/test-client.py:test_003()/206 cmd: $NMCLI --mode multiline c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 5939 bytes +stdout: 6438 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -10181,6 +10635,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -10217,13 +10674,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -10232,9 +10691,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -10248,6 +10710,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -10263,7 +10726,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -10287,12 +10751,12 @@ GENERAL.ZONE: -- GENERAL.MASTER-PATH: -- <<< -size: 6170 +size: 6669 location: src/tests/client/test-client.py:test_003()/207 cmd: $NMCLI --mode multiline c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 5969 bytes +stdout: 6468 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -10316,6 +10780,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -10352,13 +10819,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -10367,9 +10836,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -10383,6 +10855,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -10398,7 +10871,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -10836,12 +11310,12 @@ UUID: UUID-con-xx1-REPLACED-REPLACED-REPLA TYPE: ethernet <<< -size: 6812 +size: 7311 location: src/tests/client/test-client.py:test_003()/214 cmd: $NMCLI --mode multiline --color yes con s ethernet lang: C returncode: 0 -stdout: 6649 bytes +stdout: 7148 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -10865,6 +11339,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -10901,13 +11378,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -10916,9 +11395,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -10932,6 +11414,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -10947,7 +11430,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -10985,12 +11469,12 @@ GENERAL.ZONE: -- GENERAL.MASTER-PATH: -- <<< -size: 6856 +size: 7355 location: src/tests/client/test-client.py:test_003()/215 cmd: $NMCLI --mode multiline --color yes con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 6683 bytes +stdout: 7182 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -11014,6 +11498,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -11050,13 +11537,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -11065,9 +11554,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -11081,6 +11573,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -11096,7 +11589,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -11134,12 +11628,12 @@ GENERAL.ZONE: -- GENERAL.MASTER-PATH: -- <<< -size: 6142 +size: 6641 location: src/tests/client/test-client.py:test_003()/216 cmd: $NMCLI --mode multiline --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 5939 bytes +stdout: 6438 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -11163,6 +11657,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -11199,13 +11696,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -11214,9 +11713,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -11230,6 +11732,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -11245,7 +11748,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -11269,12 +11773,12 @@ GENERAL.ZONE: -- GENERAL.MASTER-PATH: -- <<< -size: 6182 +size: 6681 location: src/tests/client/test-client.py:test_003()/217 cmd: $NMCLI --mode multiline --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 5969 bytes +stdout: 6468 bytes >>> connection.id: ethernet connection.uuid: UUID-ethernet-REPLACED-REPLACED-REPL @@ -11298,6 +11802,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -11334,13 +11841,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -11349,9 +11858,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -11365,6 +11877,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -11380,7 +11893,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -11856,12 +12370,12 @@ TYPE: ethernet ------------------------------------------------------------------------------- <<< -size: 8052 +size: 8551 location: src/tests/client/test-client.py:test_003()/224 cmd: $NMCLI --mode multiline --pretty con s ethernet lang: C returncode: 0 -stdout: 7892 bytes +stdout: 8391 bytes >>> =============================================================================== Connection profile details (ethernet) @@ -11888,6 +12402,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -11926,13 +12443,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -11941,9 +12460,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -11958,6 +12480,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -11973,7 +12496,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -12021,12 +12545,12 @@ GENERAL.MASTER-PATH: -- ------------------------------------------------------------------------------- <<< -size: 8117 +size: 8616 location: src/tests/client/test-client.py:test_003()/225 cmd: $NMCLI --mode multiline --pretty con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 7947 bytes +stdout: 8446 bytes >>> =============================================================================== Szczegóły profilu połączenia (ethernet) @@ -12053,6 +12577,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -12091,13 +12618,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -12106,9 +12635,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -12123,6 +12655,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -12138,7 +12671,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -12186,12 +12720,12 @@ GENERAL.MASTER-PATH: -- ------------------------------------------------------------------------------- <<< -size: 7070 +size: 7569 location: src/tests/client/test-client.py:test_003()/226 cmd: $NMCLI --mode multiline --pretty c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 6870 bytes +stdout: 7369 bytes >>> =============================================================================== Connection profile details (ethernet) @@ -12218,6 +12752,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -12256,13 +12793,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -12271,9 +12810,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -12288,6 +12830,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -12303,7 +12846,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -12333,12 +12877,12 @@ GENERAL.MASTER-PATH: -- ------------------------------------------------------------------------------- <<< -size: 7123 +size: 7622 location: src/tests/client/test-client.py:test_003()/227 cmd: $NMCLI --mode multiline --pretty c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6913 bytes +stdout: 7412 bytes >>> =============================================================================== Szczegóły profilu połączenia (ethernet) @@ -12365,6 +12909,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -12403,13 +12950,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -12418,9 +12967,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -12435,6 +12987,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -12450,7 +13003,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -12956,12 +13510,12 @@ TYPE: ethernet ------------------------------------------------------------------------------- <<< -size: 8064 +size: 8563 location: src/tests/client/test-client.py:test_003()/234 cmd: $NMCLI --mode multiline --pretty --color yes con s ethernet lang: C returncode: 0 -stdout: 7892 bytes +stdout: 8391 bytes >>> =============================================================================== Connection profile details (ethernet) @@ -12988,6 +13542,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -13026,13 +13583,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -13041,9 +13600,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -13058,6 +13620,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -13073,7 +13636,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -13121,12 +13685,12 @@ GENERAL.MASTER-PATH: -- ------------------------------------------------------------------------------- <<< -size: 8129 +size: 8628 location: src/tests/client/test-client.py:test_003()/235 cmd: $NMCLI --mode multiline --pretty --color yes con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 7947 bytes +stdout: 8446 bytes >>> =============================================================================== Szczegóły profilu połączenia (ethernet) @@ -13153,6 +13717,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -13191,13 +13758,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -13206,9 +13775,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -13223,6 +13795,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -13238,7 +13811,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -13286,12 +13860,12 @@ GENERAL.MASTER-PATH: -- ------------------------------------------------------------------------------- <<< -size: 7082 +size: 7581 location: src/tests/client/test-client.py:test_003()/236 cmd: $NMCLI --mode multiline --pretty --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 6870 bytes +stdout: 7369 bytes >>> =============================================================================== Connection profile details (ethernet) @@ -13318,6 +13892,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -13356,13 +13933,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -13371,9 +13950,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -13388,6 +13970,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -13403,7 +13986,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -13433,12 +14017,12 @@ GENERAL.MASTER-PATH: -- ------------------------------------------------------------------------------- <<< -size: 7135 +size: 7634 location: src/tests/client/test-client.py:test_003()/237 cmd: $NMCLI --mode multiline --pretty --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6913 bytes +stdout: 7412 bytes >>> =============================================================================== Szczegóły profilu połączenia (ethernet) @@ -13465,6 +14049,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -13503,13 +14090,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -13518,9 +14107,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -13535,6 +14127,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -13550,7 +14143,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -14018,12 +14612,12 @@ UUID:UUID-con-xx1-REPLACED-REPLACED-REPLA TYPE:802-3-ethernet <<< -size: 3632 +size: 3936 location: src/tests/client/test-client.py:test_003()/244 cmd: $NMCLI --mode multiline --terse con s ethernet lang: C returncode: 0 -stdout: 3473 bytes +stdout: 3777 bytes >>> connection.id:ethernet connection.uuid:UUID-ethernet-REPLACED-REPLACED-REPL @@ -14047,6 +14641,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -14083,13 +14680,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -14098,9 +14697,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -14114,6 +14716,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -14129,7 +14732,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -14167,12 +14771,12 @@ GENERAL.ZONE: GENERAL.MASTER-PATH: <<< -size: 3642 +size: 3946 location: src/tests/client/test-client.py:test_003()/245 cmd: $NMCLI --mode multiline --terse con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 3473 bytes +stdout: 3777 bytes >>> connection.id:ethernet connection.uuid:UUID-ethernet-REPLACED-REPLACED-REPL @@ -14196,6 +14800,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -14232,13 +14839,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -14247,9 +14856,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -14263,6 +14875,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -14278,7 +14891,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -14316,12 +14930,12 @@ GENERAL.ZONE: GENERAL.MASTER-PATH: <<< -size: 3282 +size: 3586 location: src/tests/client/test-client.py:test_003()/246 cmd: $NMCLI --mode multiline --terse c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 3083 bytes +stdout: 3387 bytes >>> connection.id:ethernet connection.uuid:UUID-ethernet-REPLACED-REPLACED-REPL @@ -14345,6 +14959,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -14381,13 +14998,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -14396,9 +15015,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -14412,6 +15034,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -14427,7 +15050,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -14451,12 +15075,12 @@ GENERAL.ZONE: GENERAL.MASTER-PATH: <<< -size: 3292 +size: 3596 location: src/tests/client/test-client.py:test_003()/247 cmd: $NMCLI --mode multiline --terse c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 3083 bytes +stdout: 3387 bytes >>> connection.id:ethernet connection.uuid:UUID-ethernet-REPLACED-REPLACED-REPL @@ -14480,6 +15104,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -14516,13 +15143,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -14531,9 +15160,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -14547,6 +15179,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -14562,7 +15195,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -15000,12 +15634,12 @@ UUID:UUID-con-xx1-REPLACED-REPLACED-REPLA TYPE:802-3-ethernet <<< -size: 3644 +size: 3948 location: src/tests/client/test-client.py:test_003()/254 cmd: $NMCLI --mode multiline --terse --color yes con s ethernet lang: C returncode: 0 -stdout: 3473 bytes +stdout: 3777 bytes >>> connection.id:ethernet connection.uuid:UUID-ethernet-REPLACED-REPLACED-REPL @@ -15029,6 +15663,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -15065,13 +15702,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -15080,9 +15719,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -15096,6 +15738,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -15111,7 +15754,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -15149,12 +15793,12 @@ GENERAL.ZONE: GENERAL.MASTER-PATH: <<< -size: 3654 +size: 3958 location: src/tests/client/test-client.py:test_003()/255 cmd: $NMCLI --mode multiline --terse --color yes con s ethernet lang: pl_PL.UTF-8 returncode: 0 -stdout: 3473 bytes +stdout: 3777 bytes >>> connection.id:ethernet connection.uuid:UUID-ethernet-REPLACED-REPLACED-REPL @@ -15178,6 +15822,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -15214,13 +15861,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -15229,9 +15878,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -15245,6 +15897,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -15260,7 +15913,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -15298,12 +15952,12 @@ GENERAL.ZONE: GENERAL.MASTER-PATH: <<< -size: 3294 +size: 3598 location: src/tests/client/test-client.py:test_003()/256 cmd: $NMCLI --mode multiline --terse --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: C returncode: 0 -stdout: 3083 bytes +stdout: 3387 bytes >>> connection.id:ethernet connection.uuid:UUID-ethernet-REPLACED-REPLACED-REPL @@ -15327,6 +15981,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -15363,13 +16020,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -15378,9 +16037,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -15394,6 +16056,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -15409,7 +16072,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -15433,12 +16097,12 @@ GENERAL.ZONE: GENERAL.MASTER-PATH: <<< -size: 3304 +size: 3608 location: src/tests/client/test-client.py:test_003()/257 cmd: $NMCLI --mode multiline --terse --color yes c s /org/freedesktop/NetworkManager/ActiveConnection/1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 3083 bytes +stdout: 3387 bytes >>> connection.id:ethernet connection.uuid:UUID-ethernet-REPLACED-REPLACED-REPL @@ -15462,6 +16126,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -15498,13 +16165,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -15513,9 +16182,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -15529,6 +16201,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -15544,7 +16217,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 diff --git a/src/tests/client/test-client.check-on-disk/test_004.expected b/src/tests/client/test-client.check-on-disk/test_004.expected index b10b604f..5ba751ce 100644 --- a/src/tests/client/test-client.check-on-disk/test_004.expected +++ b/src/tests/client/test-client.check-on-disk/test_004.expected @@ -58,12 +58,12 @@ location: src/tests/client/test-client.py:test_004()/7 cmd: $NMCLI connection mod con-xx1 ipv4.addresses 192.168.77.5/24 ipv4.routes '2.3.4.5/32 192.168.77.1' ipv6.addresses 1:2:3:4::6/64 ipv6.routes 1:2:3:4:5:6::5/128 lang: C returncode: 0 -size: 5647 +size: 6146 location: src/tests/client/test-client.py:test_004()/8 cmd: $NMCLI con s con-xx1 lang: C returncode: 0 -stdout: 5516 bytes +stdout: 6015 bytes >>> connection.id: con-xx1 connection.uuid: UUID-con-xx1-REPLACED-REPLACED-REPLA @@ -87,6 +87,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -126,13 +129,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -141,9 +146,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -157,6 +165,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -172,7 +181,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -183,12 +193,12 @@ proxy.pac-url: -- proxy.pac-script: -- <<< -size: 5682 +size: 6181 location: src/tests/client/test-client.py:test_004()/9 cmd: $NMCLI con s con-xx1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 5541 bytes +stdout: 6040 bytes >>> connection.id: con-xx1 connection.uuid: UUID-con-xx1-REPLACED-REPLACED-REPLA @@ -212,6 +222,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -251,13 +264,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -266,9 +281,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -282,6 +300,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -297,7 +316,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -344,12 +364,12 @@ con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP vpn -- con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA wifi -- <<< -size: 5023 +size: 5522 location: src/tests/client/test-client.py:test_004()/13 cmd: $NMCLI con s con-vpn-1 lang: C returncode: 0 -stdout: 4889 bytes +stdout: 5388 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -373,6 +393,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -394,13 +417,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -409,9 +434,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -425,6 +453,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -440,7 +469,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -457,12 +487,12 @@ proxy.pac-url: -- proxy.pac-script: -- <<< -size: 5050 +size: 5549 location: src/tests/client/test-client.py:test_004()/14 cmd: $NMCLI con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 4906 bytes +stdout: 5405 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -486,6 +516,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -507,13 +540,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -522,9 +557,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -538,6 +576,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -553,7 +592,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -642,12 +682,12 @@ con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA wifi wlan0 con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet -- <<< -size: 6151 +size: 6650 location: src/tests/client/test-client.py:test_004()/21 cmd: $NMCLI con s con-vpn-1 lang: C returncode: 0 -stdout: 6017 bytes +stdout: 6516 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -671,6 +711,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -692,13 +735,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -707,9 +752,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -723,6 +771,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -738,7 +787,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -776,12 +826,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 6184 +size: 6683 location: src/tests/client/test-client.py:test_004()/22 cmd: $NMCLI con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6040 bytes +stdout: 6539 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -805,6 +855,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -826,13 +879,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -841,9 +896,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -857,6 +915,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -872,7 +931,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -1018,12 +1078,12 @@ con-xx1 UUID-con-xx1-REPLACED-REPLACED-REPLA wifi 0 never con-1 5fcfd6d7-1e63-3332-8826-a7eda103792d ethernet 0 never yes 0 no /org/freedesktop/NetworkManager/Settings/Connection/1 no -- -- -- -- /etc/NetworkManager/system-connections/con-1 <<< -size: 6157 +size: 6656 location: src/tests/client/test-client.py:test_004()/27 cmd: $NMCLI con s con-vpn-1 lang: C returncode: 0 -stdout: 6023 bytes +stdout: 6522 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -1047,6 +1107,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -1068,13 +1131,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -1083,9 +1148,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -1099,6 +1167,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -1114,7 +1183,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -1152,12 +1222,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 6194 +size: 6693 location: src/tests/client/test-client.py:test_004()/28 cmd: $NMCLI con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6050 bytes +stdout: 6549 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -1181,6 +1251,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -1202,13 +1275,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -1217,9 +1292,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -1233,6 +1311,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -1248,7 +1327,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -1286,12 +1366,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 6157 +size: 6656 location: src/tests/client/test-client.py:test_004()/29 cmd: $NMCLI con s con-vpn-1 lang: C returncode: 0 -stdout: 6023 bytes +stdout: 6522 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -1315,6 +1395,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -1336,13 +1419,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -1351,9 +1436,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -1367,6 +1455,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -1382,7 +1471,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -1420,12 +1510,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 6194 +size: 6693 location: src/tests/client/test-client.py:test_004()/30 cmd: $NMCLI con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6050 bytes +stdout: 6549 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -1449,6 +1539,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -1470,13 +1563,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -1485,9 +1580,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -1501,6 +1599,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -1516,7 +1615,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -1554,12 +1654,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 5030 +size: 5529 location: src/tests/client/test-client.py:test_004()/31 cmd: $NMCLI -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 4889 bytes +stdout: 5388 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -1583,6 +1683,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -1604,13 +1707,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -1619,9 +1724,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -1635,6 +1743,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -1650,7 +1759,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -1667,12 +1777,12 @@ proxy.pac-url: -- proxy.pac-script: -- <<< -size: 5057 +size: 5556 location: src/tests/client/test-client.py:test_004()/32 cmd: $NMCLI -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 4906 bytes +stdout: 5405 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -1696,6 +1806,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -1717,13 +1830,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -1732,9 +1847,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -1748,6 +1866,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -1763,7 +1882,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -4390,12 +4510,12 @@ connection.type: 802-11-wireless connection.interface-name: -- <<< -size: 6169 +size: 6668 location: src/tests/client/test-client.py:test_004()/77 cmd: $NMCLI --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 6023 bytes +stdout: 6522 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -4419,6 +4539,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -4440,13 +4563,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -4455,9 +4580,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -4471,6 +4599,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -4486,7 +4615,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -4524,12 +4654,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 6206 +size: 6705 location: src/tests/client/test-client.py:test_004()/78 cmd: $NMCLI --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6050 bytes +stdout: 6549 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -4553,6 +4683,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -4574,13 +4707,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -4589,9 +4724,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -4605,6 +4743,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -4620,7 +4759,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -4658,12 +4798,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 6169 +size: 6668 location: src/tests/client/test-client.py:test_004()/79 cmd: $NMCLI --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 6023 bytes +stdout: 6522 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -4687,6 +4827,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -4708,13 +4851,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -4723,9 +4868,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -4739,6 +4887,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -4754,7 +4903,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -4792,12 +4942,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 6206 +size: 6705 location: src/tests/client/test-client.py:test_004()/80 cmd: $NMCLI --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6050 bytes +stdout: 6549 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -4821,6 +4971,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -4842,13 +4995,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -4857,9 +5012,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -4873,6 +5031,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -4888,7 +5047,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -4926,12 +5086,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 5042 +size: 5541 location: src/tests/client/test-client.py:test_004()/81 cmd: $NMCLI --color yes -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 4889 bytes +stdout: 5388 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -4955,6 +5115,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -4976,13 +5139,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -4991,9 +5156,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -5007,6 +5175,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -5022,7 +5191,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -5039,12 +5209,12 @@ proxy.pac-url: -- proxy.pac-script: -- <<< -size: 5069 +size: 5568 location: src/tests/client/test-client.py:test_004()/82 cmd: $NMCLI --color yes -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 4906 bytes +stdout: 5405 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -5068,6 +5238,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -5089,13 +5262,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -5104,9 +5279,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -5120,6 +5298,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -5135,7 +5314,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -7762,12 +7942,12 @@ connection.type: 802-11-wireless connection.interface-name: -- <<< -size: 7178 +size: 7677 location: src/tests/client/test-client.py:test_004()/127 cmd: $NMCLI --pretty con s con-vpn-1 lang: C returncode: 0 -stdout: 7034 bytes +stdout: 7533 bytes >>> =============================================================================== Connection profile details (con-vpn-1) @@ -7794,6 +7974,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -7816,13 +7999,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -7831,9 +8016,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -7848,6 +8036,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -7863,7 +8052,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -7909,12 +8099,12 @@ VPN.CFG[3]: key3 = val3 ------------------------------------------------------------------------------- <<< -size: 7228 +size: 7727 location: src/tests/client/test-client.py:test_004()/128 cmd: $NMCLI --pretty con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 7074 bytes +stdout: 7573 bytes >>> =============================================================================== Szczegóły profilu połączenia (con-vpn-1) @@ -7941,6 +8131,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -7963,13 +8156,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -7978,9 +8173,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -7995,6 +8193,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -8010,7 +8209,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -8056,12 +8256,12 @@ VPN.CFG[3]: key3 = val3 ------------------------------------------------------------------------------- <<< -size: 7178 +size: 7677 location: src/tests/client/test-client.py:test_004()/129 cmd: $NMCLI --pretty con s con-vpn-1 lang: C returncode: 0 -stdout: 7034 bytes +stdout: 7533 bytes >>> =============================================================================== Connection profile details (con-vpn-1) @@ -8088,6 +8288,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -8110,13 +8313,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -8125,9 +8330,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -8142,6 +8350,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -8157,7 +8366,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -8203,12 +8413,12 @@ VPN.CFG[3]: key3 = val3 ------------------------------------------------------------------------------- <<< -size: 7228 +size: 7727 location: src/tests/client/test-client.py:test_004()/130 cmd: $NMCLI --pretty con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 7074 bytes +stdout: 7573 bytes >>> =============================================================================== Szczegóły profilu połączenia (con-vpn-1) @@ -8235,6 +8445,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -8257,13 +8470,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -8272,9 +8487,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -8289,6 +8507,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -8304,7 +8523,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -8350,12 +8570,12 @@ VPN.CFG[3]: key3 = val3 ------------------------------------------------------------------------------- <<< -size: 5659 +size: 6158 location: src/tests/client/test-client.py:test_004()/131 cmd: $NMCLI --pretty -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 5508 bytes +stdout: 6007 bytes >>> =============================================================================== Connection profile details (con-vpn-1) @@ -8382,6 +8602,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -8404,13 +8627,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -8419,9 +8644,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -8436,6 +8664,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -8451,7 +8680,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -8471,12 +8701,12 @@ proxy.pac-script: -- ------------------------------------------------------------------------------- <<< -size: 5691 +size: 6190 location: src/tests/client/test-client.py:test_004()/132 cmd: $NMCLI --pretty -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 5530 bytes +stdout: 6029 bytes >>> =============================================================================== Szczegóły profilu połączenia (con-vpn-1) @@ -8503,6 +8733,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -8525,13 +8758,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -8540,9 +8775,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -8557,6 +8795,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -8572,7 +8811,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -11806,12 +12046,12 @@ connection.interface-name: -- ------------------------------------------------------------------------------- <<< -size: 7190 +size: 7689 location: src/tests/client/test-client.py:test_004()/177 cmd: $NMCLI --pretty --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 7034 bytes +stdout: 7533 bytes >>> =============================================================================== Connection profile details (con-vpn-1) @@ -11838,6 +12078,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -11860,13 +12103,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -11875,9 +12120,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -11892,6 +12140,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -11907,7 +12156,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -11953,12 +12203,12 @@ VPN.CFG[3]: key3 = val3 ------------------------------------------------------------------------------- <<< -size: 7240 +size: 7739 location: src/tests/client/test-client.py:test_004()/178 cmd: $NMCLI --pretty --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 7074 bytes +stdout: 7573 bytes >>> =============================================================================== Szczegóły profilu połączenia (con-vpn-1) @@ -11985,6 +12235,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -12007,13 +12260,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -12022,9 +12277,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -12039,6 +12297,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -12054,7 +12313,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -12100,12 +12360,12 @@ VPN.CFG[3]: key3 = val3 ------------------------------------------------------------------------------- <<< -size: 7190 +size: 7689 location: src/tests/client/test-client.py:test_004()/179 cmd: $NMCLI --pretty --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 7034 bytes +stdout: 7533 bytes >>> =============================================================================== Connection profile details (con-vpn-1) @@ -12132,6 +12392,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -12154,13 +12417,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -12169,9 +12434,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -12186,6 +12454,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -12201,7 +12470,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -12247,12 +12517,12 @@ VPN.CFG[3]: key3 = val3 ------------------------------------------------------------------------------- <<< -size: 7240 +size: 7739 location: src/tests/client/test-client.py:test_004()/180 cmd: $NMCLI --pretty --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 7074 bytes +stdout: 7573 bytes >>> =============================================================================== Szczegóły profilu połączenia (con-vpn-1) @@ -12279,6 +12549,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -12301,13 +12574,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -12316,9 +12591,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -12333,6 +12611,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -12348,7 +12627,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -12394,12 +12674,12 @@ VPN.CFG[3]: key3 = val3 ------------------------------------------------------------------------------- <<< -size: 5671 +size: 6170 location: src/tests/client/test-client.py:test_004()/181 cmd: $NMCLI --pretty --color yes -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 5508 bytes +stdout: 6007 bytes >>> =============================================================================== Connection profile details (con-vpn-1) @@ -12426,6 +12706,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -12448,13 +12731,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -12463,9 +12748,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -12480,6 +12768,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -12495,7 +12784,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -12515,12 +12805,12 @@ proxy.pac-script: -- ------------------------------------------------------------------------------- <<< -size: 5703 +size: 6202 location: src/tests/client/test-client.py:test_004()/182 cmd: $NMCLI --pretty --color yes -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 5530 bytes +stdout: 6029 bytes >>> =============================================================================== Szczegóły profilu połączenia (con-vpn-1) @@ -12547,6 +12837,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -12569,13 +12862,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -12584,9 +12879,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -12601,6 +12899,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -12616,7 +12915,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -15850,12 +16150,12 @@ connection.interface-name: -- ------------------------------------------------------------------------------- <<< -size: 3105 +size: 3409 location: src/tests/client/test-client.py:test_004()/227 cmd: $NMCLI --terse con s con-vpn-1 lang: C returncode: 0 -stdout: 2962 bytes +stdout: 3266 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -15879,6 +16179,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -15900,13 +16203,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -15915,9 +16220,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -15931,6 +16239,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -15946,7 +16255,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -15984,12 +16294,12 @@ VPN.CFG[2]:key2 = val2 VPN.CFG[3]:key3 = val3 <<< -size: 3115 +size: 3419 location: src/tests/client/test-client.py:test_004()/228 cmd: $NMCLI --terse con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 2962 bytes +stdout: 3266 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -16013,6 +16323,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -16034,13 +16347,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -16049,9 +16364,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -16065,6 +16383,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -16080,7 +16399,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -16118,12 +16438,12 @@ VPN.CFG[2]:key2 = val2 VPN.CFG[3]:key3 = val3 <<< -size: 3105 +size: 3409 location: src/tests/client/test-client.py:test_004()/229 cmd: $NMCLI --terse con s con-vpn-1 lang: C returncode: 0 -stdout: 2962 bytes +stdout: 3266 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -16147,6 +16467,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -16168,13 +16491,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -16183,9 +16508,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -16199,6 +16527,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -16214,7 +16543,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -16252,12 +16582,12 @@ VPN.CFG[2]:key2 = val2 VPN.CFG[3]:key3 = val3 <<< -size: 3115 +size: 3419 location: src/tests/client/test-client.py:test_004()/230 cmd: $NMCLI --terse con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 2962 bytes +stdout: 3266 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -16281,6 +16611,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -16302,13 +16635,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -16317,9 +16652,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -16333,6 +16671,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -16348,7 +16687,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -16386,12 +16726,12 @@ VPN.CFG[2]:key2 = val2 VPN.CFG[3]:key3 = val3 <<< -size: 2530 +size: 2834 location: src/tests/client/test-client.py:test_004()/231 cmd: $NMCLI --terse -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 2380 bytes +stdout: 2684 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -16415,6 +16755,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -16436,13 +16779,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -16451,9 +16796,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -16467,6 +16815,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -16482,7 +16831,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -16499,12 +16849,12 @@ proxy.pac-url: proxy.pac-script: <<< -size: 2540 +size: 2844 location: src/tests/client/test-client.py:test_004()/232 cmd: $NMCLI --terse -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 2380 bytes +stdout: 2684 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -16528,6 +16878,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -16549,13 +16902,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -16564,9 +16919,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -16580,6 +16938,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -16595,7 +16954,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -19192,12 +19552,12 @@ connection.type:802-11-wireless connection.interface-name: <<< -size: 3117 +size: 3421 location: src/tests/client/test-client.py:test_004()/277 cmd: $NMCLI --terse --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 2962 bytes +stdout: 3266 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -19221,6 +19581,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -19242,13 +19605,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -19257,9 +19622,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -19273,6 +19641,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -19288,7 +19657,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -19326,12 +19696,12 @@ VPN.CFG[2]:key2 = val2 VPN.CFG[3]:key3 = val3 <<< -size: 3127 +size: 3431 location: src/tests/client/test-client.py:test_004()/278 cmd: $NMCLI --terse --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 2962 bytes +stdout: 3266 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -19355,6 +19725,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -19376,13 +19749,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -19391,9 +19766,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -19407,6 +19785,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -19422,7 +19801,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -19460,12 +19840,12 @@ VPN.CFG[2]:key2 = val2 VPN.CFG[3]:key3 = val3 <<< -size: 3117 +size: 3421 location: src/tests/client/test-client.py:test_004()/279 cmd: $NMCLI --terse --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 2962 bytes +stdout: 3266 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -19489,6 +19869,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -19510,13 +19893,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -19525,9 +19910,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -19541,6 +19929,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -19556,7 +19945,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -19594,12 +19984,12 @@ VPN.CFG[2]:key2 = val2 VPN.CFG[3]:key3 = val3 <<< -size: 3127 +size: 3431 location: src/tests/client/test-client.py:test_004()/280 cmd: $NMCLI --terse --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 2962 bytes +stdout: 3266 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -19623,6 +20013,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -19644,13 +20037,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -19659,9 +20054,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -19675,6 +20073,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -19690,7 +20089,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -19728,12 +20128,12 @@ VPN.CFG[2]:key2 = val2 VPN.CFG[3]:key3 = val3 <<< -size: 2542 +size: 2846 location: src/tests/client/test-client.py:test_004()/281 cmd: $NMCLI --terse --color yes -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 2380 bytes +stdout: 2684 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -19757,6 +20157,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -19778,13 +20181,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -19793,9 +20198,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -19809,6 +20217,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -19824,7 +20233,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -19841,12 +20251,12 @@ proxy.pac-url: proxy.pac-script: <<< -size: 2552 +size: 2856 location: src/tests/client/test-client.py:test_004()/282 cmd: $NMCLI --terse --color yes -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 2380 bytes +stdout: 2684 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -19870,6 +20280,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -19891,13 +20304,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -19906,9 +20321,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -19922,6 +20340,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -19937,7 +20356,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -22534,21 +22954,21 @@ connection.type:802-11-wireless connection.interface-name: <<< -size: 4066 +size: 4518 location: src/tests/client/test-client.py:test_004()/327 cmd: $NMCLI --mode tabular con s con-vpn-1 lang: C returncode: 0 -stdout: 3916 bytes +stdout: 4368 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout vpn org.freedesktop.NetworkManager.openvpn -- key1 = val1, key2 = val2, key3 = val3 <hidden> no 0 @@ -22563,21 +22983,21 @@ NAME TYPE USERNAME GATEWAY BANNER VPN-STATE VPN openvpn -- -- *** VPN connection con-vpn-1 *** 5 - VPN connected key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 4105 +size: 4557 location: src/tests/client/test-client.py:test_004()/328 cmd: $NMCLI --mode tabular con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 3945 bytes +stdout: 4397 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout vpn org.freedesktop.NetworkManager.openvpn -- key1 = val1, key2 = val2, key3 = val3 <hidden> nie 0 @@ -22592,21 +23012,21 @@ NAME TYPE USERNAME GATEWAY BANNER VPN-STATE VPN openvpn -- -- *** VPN connection con-vpn-1 *** 5 — Połączono z VPN key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 4066 +size: 4518 location: src/tests/client/test-client.py:test_004()/329 cmd: $NMCLI --mode tabular con s con-vpn-1 lang: C returncode: 0 -stdout: 3916 bytes +stdout: 4368 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout vpn org.freedesktop.NetworkManager.openvpn -- key1 = val1, key2 = val2, key3 = val3 <hidden> no 0 @@ -22621,21 +23041,21 @@ NAME TYPE USERNAME GATEWAY BANNER VPN-STATE VPN openvpn -- -- *** VPN connection con-vpn-1 *** 5 - VPN connected key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 4105 +size: 4557 location: src/tests/client/test-client.py:test_004()/330 cmd: $NMCLI --mode tabular con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 3945 bytes +stdout: 4397 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout vpn org.freedesktop.NetworkManager.openvpn -- key1 = val1, key2 = val2, key3 = val3 <hidden> nie 0 @@ -22650,21 +23070,21 @@ NAME TYPE USERNAME GATEWAY BANNER VPN-STATE VPN openvpn -- -- *** VPN connection con-vpn-1 *** 5 — Połączono z VPN key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 3314 +size: 3766 location: src/tests/client/test-client.py:test_004()/331 cmd: $NMCLI --mode tabular -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 3157 bytes +stdout: 3609 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout vpn org.freedesktop.NetworkManager.openvpn -- key1 = val1, key2 = val2, key3 = val3 <hidden> no 0 @@ -22674,21 +23094,21 @@ proxy none no -- -- <<< -size: 3342 +size: 3794 location: src/tests/client/test-client.py:test_004()/332 cmd: $NMCLI --mode tabular -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 3175 bytes +stdout: 3627 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout vpn org.freedesktop.NetworkManager.openvpn -- key1 = val1, key2 = val2, key3 = val3 <hidden> nie 0 @@ -24188,21 +24608,21 @@ interface-name <<< -size: 4078 +size: 4530 location: src/tests/client/test-client.py:test_004()/377 cmd: $NMCLI --mode tabular --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 3916 bytes +stdout: 4368 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout vpn org.freedesktop.NetworkManager.openvpn -- key1 = val1, key2 = val2, key3 = val3 <hidden> no 0 @@ -24217,21 +24637,21 @@ NAME TYPE USERNAME GATEWAY BANNER VPN-STATE VPN openvpn -- -- *** VPN connection con-vpn-1 *** 5 - VPN connected key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 4117 +size: 4569 location: src/tests/client/test-client.py:test_004()/378 cmd: $NMCLI --mode tabular --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 3945 bytes +stdout: 4397 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout vpn org.freedesktop.NetworkManager.openvpn -- key1 = val1, key2 = val2, key3 = val3 <hidden> nie 0 @@ -24246,21 +24666,21 @@ NAME TYPE USERNAME GATEWAY BANNER VPN-STATE VPN openvpn -- -- *** VPN connection con-vpn-1 *** 5 — Połączono z VPN key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 4078 +size: 4530 location: src/tests/client/test-client.py:test_004()/379 cmd: $NMCLI --mode tabular --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 3916 bytes +stdout: 4368 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout vpn org.freedesktop.NetworkManager.openvpn -- key1 = val1, key2 = val2, key3 = val3 <hidden> no 0 @@ -24275,21 +24695,21 @@ NAME TYPE USERNAME GATEWAY BANNER VPN-STATE VPN openvpn -- -- *** VPN connection con-vpn-1 *** 5 - VPN connected key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 4117 +size: 4569 location: src/tests/client/test-client.py:test_004()/380 cmd: $NMCLI --mode tabular --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 3945 bytes +stdout: 4397 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout vpn org.freedesktop.NetworkManager.openvpn -- key1 = val1, key2 = val2, key3 = val3 <hidden> nie 0 @@ -24304,21 +24724,21 @@ NAME TYPE USERNAME GATEWAY BANNER VPN-STATE VPN openvpn -- -- *** VPN connection con-vpn-1 *** 5 — Połączono z VPN key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 3326 +size: 3778 location: src/tests/client/test-client.py:test_004()/381 cmd: $NMCLI --mode tabular --color yes -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 3157 bytes +stdout: 3609 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout vpn org.freedesktop.NetworkManager.openvpn -- key1 = val1, key2 = val2, key3 = val3 <hidden> no 0 @@ -24328,21 +24748,21 @@ proxy none no -- -- <<< -size: 3354 +size: 3806 location: src/tests/client/test-client.py:test_004()/382 cmd: $NMCLI --mode tabular --color yes -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 3175 bytes +stdout: 3627 bytes >>> -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout vpn org.freedesktop.NetworkManager.openvpn -- key1 = val1, key2 = val2, key3 = val3 <hidden> nie 0 @@ -25842,27 +26262,27 @@ interface-name <<< -size: 6369 +size: 7047 location: src/tests/client/test-client.py:test_004()/427 cmd: $NMCLI --mode tabular --pretty con s con-vpn-1 lang: C returncode: 0 -stdout: 6210 bytes +stdout: 6888 bytes >>> ========================================== Connection profile details (con-vpn-1) ========================================== -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout ------------------------------------------------------------------------------------------------------------------------------- @@ -25884,27 +26304,27 @@ NAME TYPE USERNAME GATEWAY BANNER VPN-STATE VPN openvpn -- -- *** VPN connection con-vpn-1 *** 5 - VPN connected key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 6455 +size: 7133 location: src/tests/client/test-client.py:test_004()/428 cmd: $NMCLI --mode tabular --pretty con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6286 bytes +stdout: 6964 bytes >>> ============================================ Szczegóły profilu połączenia (con-vpn-1) ============================================ -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout ------------------------------------------------------------------------------------------------------------------------------- @@ -25926,27 +26346,27 @@ NAME TYPE USERNAME GATEWAY BANNER VPN-STATE VPN openvpn -- -- *** VPN connection con-vpn-1 *** 5 — Połączono z VPN key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 6369 +size: 7047 location: src/tests/client/test-client.py:test_004()/429 cmd: $NMCLI --mode tabular --pretty con s con-vpn-1 lang: C returncode: 0 -stdout: 6210 bytes +stdout: 6888 bytes >>> ========================================== Connection profile details (con-vpn-1) ========================================== -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout ------------------------------------------------------------------------------------------------------------------------------- @@ -25968,27 +26388,27 @@ NAME TYPE USERNAME GATEWAY BANNER VPN-STATE VPN openvpn -- -- *** VPN connection con-vpn-1 *** 5 - VPN connected key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 6455 +size: 7133 location: src/tests/client/test-client.py:test_004()/430 cmd: $NMCLI --mode tabular --pretty con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6286 bytes +stdout: 6964 bytes >>> ============================================ Szczegóły profilu połączenia (con-vpn-1) ============================================ -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout ------------------------------------------------------------------------------------------------------------------------------- @@ -26010,27 +26430,27 @@ NAME TYPE USERNAME GATEWAY BANNER VPN-STATE VPN openvpn -- -- *** VPN connection con-vpn-1 *** 5 — Połączono z VPN key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 5031 +size: 5709 location: src/tests/client/test-client.py:test_004()/431 cmd: $NMCLI --mode tabular --pretty -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 4865 bytes +stdout: 5543 bytes >>> ========================================== Connection profile details (con-vpn-1) ========================================== -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout ------------------------------------------------------------------------------------------------------------------------------- @@ -26042,27 +26462,27 @@ proxy none no -- -- <<< -size: 5078 +size: 5756 location: src/tests/client/test-client.py:test_004()/432 cmd: $NMCLI --mode tabular --pretty -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 4902 bytes +stdout: 5580 bytes >>> ============================================ Szczegóły profilu połączenia (con-vpn-1) ============================================ -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout ------------------------------------------------------------------------------------------------------------------------------- @@ -28150,27 +28570,27 @@ interface-name <<< -size: 6381 +size: 7059 location: src/tests/client/test-client.py:test_004()/477 cmd: $NMCLI --mode tabular --pretty --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 6210 bytes +stdout: 6888 bytes >>> ========================================== Connection profile details (con-vpn-1) ========================================== -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout ------------------------------------------------------------------------------------------------------------------------------- @@ -28192,27 +28612,27 @@ NAME TYPE USERNAME GATEWAY BANNER VPN-STATE VPN openvpn -- -- *** VPN connection con-vpn-1 *** 5 - VPN connected key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 6467 +size: 7145 location: src/tests/client/test-client.py:test_004()/478 cmd: $NMCLI --mode tabular --pretty --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6286 bytes +stdout: 6964 bytes >>> ============================================ Szczegóły profilu połączenia (con-vpn-1) ============================================ -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout ------------------------------------------------------------------------------------------------------------------------------- @@ -28234,27 +28654,27 @@ NAME TYPE USERNAME GATEWAY BANNER VPN-STATE VPN openvpn -- -- *** VPN connection con-vpn-1 *** 5 — Połączono z VPN key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 6381 +size: 7059 location: src/tests/client/test-client.py:test_004()/479 cmd: $NMCLI --mode tabular --pretty --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 6210 bytes +stdout: 6888 bytes >>> ========================================== Connection profile details (con-vpn-1) ========================================== -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout ------------------------------------------------------------------------------------------------------------------------------- @@ -28276,27 +28696,27 @@ NAME TYPE USERNAME GATEWAY BANNER VPN-STATE VPN openvpn -- -- *** VPN connection con-vpn-1 *** 5 - VPN connected key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 6467 +size: 7145 location: src/tests/client/test-client.py:test_004()/480 cmd: $NMCLI --mode tabular --pretty --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6286 bytes +stdout: 6964 bytes >>> ============================================ Szczegóły profilu połączenia (con-vpn-1) ============================================ -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout ------------------------------------------------------------------------------------------------------------------------------- @@ -28318,27 +28738,27 @@ NAME TYPE USERNAME GATEWAY BANNER VPN-STATE VPN openvpn -- -- *** VPN connection con-vpn-1 *** 5 — Połączono z VPN key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 5043 +size: 5721 location: src/tests/client/test-client.py:test_004()/481 cmd: $NMCLI --mode tabular --pretty --color yes -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 4865 bytes +stdout: 5543 bytes >>> ========================================== Connection profile details (con-vpn-1) ========================================== -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- yes 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) unknown default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no -- -- -- 0 (default) yes -- -- 0x0 (none) no yes -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no -- -- -- 0 (default) yes -1 (default) -- -- 0x0 (none) no yes -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) no no no yes -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) auto -- -- -- 0 (default) yes -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout ------------------------------------------------------------------------------------------------------------------------------- @@ -28350,27 +28770,27 @@ proxy none no -- -- <<< -size: 5090 +size: 5768 location: src/tests/client/test-client.py:test_004()/482 cmd: $NMCLI --mode tabular --pretty --color yes -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 4902 bytes +stdout: 5580 bytes >>> ============================================ Szczegóły profilu połączenia (con-vpn-1) ============================================ -name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 +name id uuid stable-id type interface-name autoconnect autoconnect-priority autoconnect-retries multi-connect auth-retries timestamp permissions zone controller master slave-type port-type autoconnect-slaves autoconnect-ports down-on-poweroff secondaries gateway-ping-timeout ip-ping-timeout ip-ping-addresses ip-ping-addresses-require-all metered lldp mdns llmnr dns-over-tls mptcp-flags wait-device-timeout wait-activation-delay +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +connection con-vpn-1 UUID-con-vpn-1-REPLACED-REPLACED-REP -- vpn -- tak 0 -1 (default) 0 (default) -1 0 -- -- -- -- -- -- -1 (default) -1 (default) -1 (default) -- 0 0 -- -1 (default) nieznane default -1 (default) -1 (default) -1 (default) 0x0 (default) -1 -1 -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier link-local dhcp-reject-servers auto-route-ext-gw -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- 0 (default) -- -1 (default) +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns dhcp-client-id dhcp-iaid dhcp-dscp dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-fqdn dhcp-hostname-flags never-default may-fail required-timeout dad-timeout dhcp-vendor-class-identifier dhcp-ipv6-only-preferred link-local dhcp-reject-servers auto-route-ext-gw shared-dhcp-range shared-dhcp-lease-time +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv4 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie -- -- -- 0 (default) tak -1 (default) -- -- 0x0 (none) nie tak -1 (default) -1 (default) -- -1 (default) 0 (default) -- -1 (default) -- 0 (default) -name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -- 0x0 (none) -1 (default) -- +name method dns dns-search dns-options dns-priority addresses gateway routes route-metric route-table routing-rules replace-local-rule dhcp-send-release routed-dns ignore-auto-routes ignore-auto-dns never-default may-fail required-timeout ip6-privacy temp-valid-lifetime temp-preferred-lifetime addr-gen-mode ra-timeout mtu dhcp-pd-hint dhcp-duid dhcp-iaid dhcp-timeout dhcp-send-hostname-deprecated dhcp-send-hostname dhcp-hostname dhcp-hostname-flags auto-route-ext-gw token +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +ipv6 auto -- -- -- 0 -- -- -- -1 0 (unspec) -- -1 (default) -1 (default) -1 (default) nie nie nie tak -1 (default) -1 (default) 0 (default) 0 (default) default 0 (default) automatyczne -- -- -- 0 (default) tak -1 (default) -- 0x0 (none) -1 (default) -- name service-type user-name data secrets persistent timeout ------------------------------------------------------------------------------------------------------------------------------- @@ -30458,94 +30878,94 @@ interface-name <<< -size: 859 +size: 883 location: src/tests/client/test-client.py:test_004()/527 cmd: $NMCLI --mode tabular --terse con s con-vpn-1 lang: C returncode: 0 -stdout: 702 bytes +stdout: 726 bytes >>> -connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: vpn:org.freedesktop.NetworkManager.openvpn::key1 = val1, key2 = val2, key3 = val3:<hidden>:no:0 proxy:none:no:: GENERAL:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP:wlan0:wlan0:activated:no:no::yes:/org/freedesktop/NetworkManager/ActiveConnection/2:/org/freedesktop/NetworkManager/Settings/Connection/3:: VPN:openvpn:::*** VPN connection con-vpn-1 ***:5 - VPN connected:key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 869 +size: 893 location: src/tests/client/test-client.py:test_004()/528 cmd: $NMCLI --mode tabular --terse con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 702 bytes +stdout: 726 bytes >>> -connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: vpn:org.freedesktop.NetworkManager.openvpn::key1 = val1, key2 = val2, key3 = val3:<hidden>:no:0 proxy:none:no:: GENERAL:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP:wlan0:wlan0:activated:no:no::yes:/org/freedesktop/NetworkManager/ActiveConnection/2:/org/freedesktop/NetworkManager/Settings/Connection/3:: VPN:openvpn:::*** VPN connection con-vpn-1 ***:5 - VPN connected:key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 859 +size: 883 location: src/tests/client/test-client.py:test_004()/529 cmd: $NMCLI --mode tabular --terse con s con-vpn-1 lang: C returncode: 0 -stdout: 702 bytes +stdout: 726 bytes >>> -connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: vpn:org.freedesktop.NetworkManager.openvpn::key1 = val1, key2 = val2, key3 = val3:<hidden>:no:0 proxy:none:no:: GENERAL:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP:wlan0:wlan0:activated:no:no::yes:/org/freedesktop/NetworkManager/ActiveConnection/2:/org/freedesktop/NetworkManager/Settings/Connection/3:: VPN:openvpn:::*** VPN connection con-vpn-1 ***:5 - VPN connected:key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 869 +size: 893 location: src/tests/client/test-client.py:test_004()/530 cmd: $NMCLI --mode tabular --terse con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 702 bytes +stdout: 726 bytes >>> -connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: vpn:org.freedesktop.NetworkManager.openvpn::key1 = val1, key2 = val2, key3 = val3:<hidden>:no:0 proxy:none:no:: GENERAL:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP:wlan0:wlan0:activated:no:no::yes:/org/freedesktop/NetworkManager/ActiveConnection/2:/org/freedesktop/NetworkManager/Settings/Connection/3:: VPN:openvpn:::*** VPN connection con-vpn-1 ***:5 - VPN connected:key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 566 +size: 590 location: src/tests/client/test-client.py:test_004()/531 cmd: $NMCLI --mode tabular --terse -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 402 bytes +stdout: 426 bytes >>> -connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: vpn:org.freedesktop.NetworkManager.openvpn::key1 = val1, key2 = val2, key3 = val3:<hidden>:no:0 proxy:none:no:: <<< -size: 576 +size: 600 location: src/tests/client/test-client.py:test_004()/532 cmd: $NMCLI --mode tabular --terse -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 402 bytes +stdout: 426 bytes >>> -connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: vpn:org.freedesktop.NetworkManager.openvpn::key1 = val1, key2 = val2, key3 = val3:<hidden>:no:0 proxy:none:no:: @@ -31396,94 +31816,94 @@ UUID-con-xx1-REPLACED-REPLACED-REPLA <<< -size: 871 +size: 895 location: src/tests/client/test-client.py:test_004()/577 cmd: $NMCLI --mode tabular --terse --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 702 bytes +stdout: 726 bytes >>> -connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: vpn:org.freedesktop.NetworkManager.openvpn::key1 = val1, key2 = val2, key3 = val3:<hidden>:no:0 proxy:none:no:: GENERAL:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP:wlan0:wlan0:activated:no:no::yes:/org/freedesktop/NetworkManager/ActiveConnection/2:/org/freedesktop/NetworkManager/Settings/Connection/3:: VPN:openvpn:::*** VPN connection con-vpn-1 ***:5 - VPN connected:key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 881 +size: 905 location: src/tests/client/test-client.py:test_004()/578 cmd: $NMCLI --mode tabular --terse --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 702 bytes +stdout: 726 bytes >>> -connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: vpn:org.freedesktop.NetworkManager.openvpn::key1 = val1, key2 = val2, key3 = val3:<hidden>:no:0 proxy:none:no:: GENERAL:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP:wlan0:wlan0:activated:no:no::yes:/org/freedesktop/NetworkManager/ActiveConnection/2:/org/freedesktop/NetworkManager/Settings/Connection/3:: VPN:openvpn:::*** VPN connection con-vpn-1 ***:5 - VPN connected:key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 871 +size: 895 location: src/tests/client/test-client.py:test_004()/579 cmd: $NMCLI --mode tabular --terse --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 702 bytes +stdout: 726 bytes >>> -connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: vpn:org.freedesktop.NetworkManager.openvpn::key1 = val1, key2 = val2, key3 = val3:<hidden>:no:0 proxy:none:no:: GENERAL:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP:wlan0:wlan0:activated:no:no::yes:/org/freedesktop/NetworkManager/ActiveConnection/2:/org/freedesktop/NetworkManager/Settings/Connection/3:: VPN:openvpn:::*** VPN connection con-vpn-1 ***:5 - VPN connected:key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 881 +size: 905 location: src/tests/client/test-client.py:test_004()/580 cmd: $NMCLI --mode tabular --terse --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 702 bytes +stdout: 726 bytes >>> -connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: vpn:org.freedesktop.NetworkManager.openvpn::key1 = val1, key2 = val2, key3 = val3:<hidden>:no:0 proxy:none:no:: GENERAL:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP:wlan0:wlan0:activated:no:no::yes:/org/freedesktop/NetworkManager/ActiveConnection/2:/org/freedesktop/NetworkManager/Settings/Connection/3:: VPN:openvpn:::*** VPN connection con-vpn-1 ***:5 - VPN connected:key1 = val1 | key2 = val2 | key3 = val3 <<< -size: 578 +size: 602 location: src/tests/client/test-client.py:test_004()/581 cmd: $NMCLI --mode tabular --terse --color yes -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 402 bytes +stdout: 426 bytes >>> -connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: vpn:org.freedesktop.NetworkManager.openvpn::key1 = val1, key2 = val2, key3 = val3:<hidden>:no:0 proxy:none:no:: <<< -size: 588 +size: 612 location: src/tests/client/test-client.py:test_004()/582 cmd: $NMCLI --mode tabular --terse --color yes -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 402 bytes +stdout: 426 bytes >>> -connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:unknown:default:-1:-1:-1:0x0:-1:-1 -ipv4:auto::::0::::-1:0::-1:-1:no:no::::0:yes:::0x0:no:yes:-1:-1::0::-1 -ipv6:auto::::0::::-1:0::-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes::0x0:-1: +connection:con-vpn-1:UUID-con-vpn-1-REPLACED-REPLACED-REP::vpn::yes:0:-1:0:-1:0:::::::-1:-1:-1::0:0::-1:unknown:default:-1:-1:-1:0x0:-1:-1 +ipv4:auto::::0::::-1:0::-1:-1:-1:no:no::::0:yes:-1:::0x0:no:yes:-1:-1::-1:0::-1::0 +ipv6:auto::::0::::-1:0::-1:-1:-1:no:no:no:yes:-1:-1:0:0:default:0:auto::::0:yes:-1::0x0:-1: vpn:org.freedesktop.NetworkManager.openvpn::key1 = val1, key2 = val2, key3 = val3:<hidden>:no:0 proxy:none:no:: @@ -32334,12 +32754,12 @@ UUID-con-xx1-REPLACED-REPLACED-REPLA <<< -size: 6175 +size: 6674 location: src/tests/client/test-client.py:test_004()/627 cmd: $NMCLI --mode multiline con s con-vpn-1 lang: C returncode: 0 -stdout: 6023 bytes +stdout: 6522 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -32363,6 +32783,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -32384,13 +32807,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -32399,9 +32824,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -32415,6 +32843,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -32430,7 +32859,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -32468,12 +32898,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 6212 +size: 6711 location: src/tests/client/test-client.py:test_004()/628 cmd: $NMCLI --mode multiline con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6050 bytes +stdout: 6549 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -32497,6 +32927,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -32518,13 +32951,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -32533,9 +32968,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -32549,6 +32987,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -32564,7 +33003,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -32602,12 +33042,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 6175 +size: 6674 location: src/tests/client/test-client.py:test_004()/629 cmd: $NMCLI --mode multiline con s con-vpn-1 lang: C returncode: 0 -stdout: 6023 bytes +stdout: 6522 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -32631,6 +33071,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -32652,13 +33095,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -32667,9 +33112,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -32683,6 +33131,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -32698,7 +33147,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -32736,12 +33186,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 6212 +size: 6711 location: src/tests/client/test-client.py:test_004()/630 cmd: $NMCLI --mode multiline con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6050 bytes +stdout: 6549 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -32765,6 +33215,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -32786,13 +33239,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -32801,9 +33256,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -32817,6 +33275,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -32832,7 +33291,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -32870,12 +33330,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 5048 +size: 5547 location: src/tests/client/test-client.py:test_004()/631 cmd: $NMCLI --mode multiline -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 4889 bytes +stdout: 5388 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -32899,6 +33359,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -32920,13 +33383,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -32935,9 +33400,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -32951,6 +33419,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -32966,7 +33435,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -32983,12 +33453,12 @@ proxy.pac-url: -- proxy.pac-script: -- <<< -size: 5075 +size: 5574 location: src/tests/client/test-client.py:test_004()/632 cmd: $NMCLI --mode multiline -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 4906 bytes +stdout: 5405 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -33012,6 +33482,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -33033,13 +33506,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -33048,9 +33523,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -33064,6 +33542,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -33079,7 +33558,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -36216,12 +36696,12 @@ connection.type: 802-11-wireless connection.interface-name: -- <<< -size: 6187 +size: 6686 location: src/tests/client/test-client.py:test_004()/677 cmd: $NMCLI --mode multiline --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 6023 bytes +stdout: 6522 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -36245,6 +36725,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -36266,13 +36749,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -36281,9 +36766,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -36297,6 +36785,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -36312,7 +36801,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -36350,12 +36840,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 6224 +size: 6723 location: src/tests/client/test-client.py:test_004()/678 cmd: $NMCLI --mode multiline --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6050 bytes +stdout: 6549 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -36379,6 +36869,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -36400,13 +36893,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -36415,9 +36910,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -36431,6 +36929,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -36446,7 +36945,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -36484,12 +36984,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 6187 +size: 6686 location: src/tests/client/test-client.py:test_004()/679 cmd: $NMCLI --mode multiline --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 6023 bytes +stdout: 6522 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -36513,6 +37013,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -36534,13 +37037,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -36549,9 +37054,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -36565,6 +37073,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -36580,7 +37089,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -36618,12 +37128,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 6224 +size: 6723 location: src/tests/client/test-client.py:test_004()/680 cmd: $NMCLI --mode multiline --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 6050 bytes +stdout: 6549 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -36647,6 +37157,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -36668,13 +37181,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -36683,9 +37198,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -36699,6 +37217,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -36714,7 +37233,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -36752,12 +37272,12 @@ VPN.CFG[2]: key2 = val2 VPN.CFG[3]: key3 = val3 <<< -size: 5060 +size: 5559 location: src/tests/client/test-client.py:test_004()/681 cmd: $NMCLI --mode multiline --color yes -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 4889 bytes +stdout: 5388 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -36781,6 +37301,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -36802,13 +37325,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -36817,9 +37342,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -36833,6 +37361,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -36848,7 +37377,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -36865,12 +37395,12 @@ proxy.pac-url: -- proxy.pac-script: -- <<< -size: 5087 +size: 5586 location: src/tests/client/test-client.py:test_004()/682 cmd: $NMCLI --mode multiline --color yes -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 4906 bytes +stdout: 5405 bytes >>> connection.id: con-vpn-1 connection.uuid: UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -36894,6 +37424,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -36915,13 +37448,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -36930,9 +37465,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ipv6.method: auto ipv6.dns: -- ipv6.dns-search: -- @@ -36946,6 +37484,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -36961,7 +37500,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -40098,12 +40638,12 @@ connection.type: 802-11-wireless connection.interface-name: -- <<< -size: 7195 +size: 7694 location: src/tests/client/test-client.py:test_004()/727 cmd: $NMCLI --mode multiline --pretty con s con-vpn-1 lang: C returncode: 0 -stdout: 7034 bytes +stdout: 7533 bytes >>> =============================================================================== Connection profile details (con-vpn-1) @@ -40130,6 +40670,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -40152,13 +40695,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -40167,9 +40712,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -40184,6 +40732,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -40199,7 +40748,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -40245,12 +40795,12 @@ VPN.CFG[3]: key3 = val3 ------------------------------------------------------------------------------- <<< -size: 7245 +size: 7744 location: src/tests/client/test-client.py:test_004()/728 cmd: $NMCLI --mode multiline --pretty con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 7074 bytes +stdout: 7573 bytes >>> =============================================================================== Szczegóły profilu połączenia (con-vpn-1) @@ -40277,6 +40827,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -40299,13 +40852,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -40314,9 +40869,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -40331,6 +40889,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -40346,7 +40905,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -40392,12 +40952,12 @@ VPN.CFG[3]: key3 = val3 ------------------------------------------------------------------------------- <<< -size: 7195 +size: 7694 location: src/tests/client/test-client.py:test_004()/729 cmd: $NMCLI --mode multiline --pretty con s con-vpn-1 lang: C returncode: 0 -stdout: 7034 bytes +stdout: 7533 bytes >>> =============================================================================== Connection profile details (con-vpn-1) @@ -40424,6 +40984,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -40446,13 +41009,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -40461,9 +41026,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -40478,6 +41046,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -40493,7 +41062,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -40539,12 +41109,12 @@ VPN.CFG[3]: key3 = val3 ------------------------------------------------------------------------------- <<< -size: 7245 +size: 7744 location: src/tests/client/test-client.py:test_004()/730 cmd: $NMCLI --mode multiline --pretty con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 7074 bytes +stdout: 7573 bytes >>> =============================================================================== Szczegóły profilu połączenia (con-vpn-1) @@ -40571,6 +41141,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -40593,13 +41166,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -40608,9 +41183,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -40625,6 +41203,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -40640,7 +41219,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -40686,12 +41266,12 @@ VPN.CFG[3]: key3 = val3 ------------------------------------------------------------------------------- <<< -size: 5676 +size: 6175 location: src/tests/client/test-client.py:test_004()/731 cmd: $NMCLI --mode multiline --pretty -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 5508 bytes +stdout: 6007 bytes >>> =============================================================================== Connection profile details (con-vpn-1) @@ -40718,6 +41298,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -40740,13 +41323,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -40755,9 +41340,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -40772,6 +41360,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -40787,7 +41376,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -40807,12 +41397,12 @@ proxy.pac-script: -- ------------------------------------------------------------------------------- <<< -size: 5708 +size: 6207 location: src/tests/client/test-client.py:test_004()/732 cmd: $NMCLI --mode multiline --pretty -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 5530 bytes +stdout: 6029 bytes >>> =============================================================================== Szczegóły profilu połączenia (con-vpn-1) @@ -40839,6 +41429,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -40861,13 +41454,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -40876,9 +41471,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -40893,6 +41491,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -40908,7 +41507,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -44682,12 +45282,12 @@ connection.interface-name: -- ------------------------------------------------------------------------------- <<< -size: 7207 +size: 7706 location: src/tests/client/test-client.py:test_004()/777 cmd: $NMCLI --mode multiline --pretty --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 7034 bytes +stdout: 7533 bytes >>> =============================================================================== Connection profile details (con-vpn-1) @@ -44714,6 +45314,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -44736,13 +45339,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -44751,9 +45356,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -44768,6 +45376,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -44783,7 +45392,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -44829,12 +45439,12 @@ VPN.CFG[3]: key3 = val3 ------------------------------------------------------------------------------- <<< -size: 7257 +size: 7756 location: src/tests/client/test-client.py:test_004()/778 cmd: $NMCLI --mode multiline --pretty --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 7074 bytes +stdout: 7573 bytes >>> =============================================================================== Szczegóły profilu połączenia (con-vpn-1) @@ -44861,6 +45471,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -44883,13 +45496,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -44898,9 +45513,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -44915,6 +45533,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -44930,7 +45549,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -44976,12 +45596,12 @@ VPN.CFG[3]: key3 = val3 ------------------------------------------------------------------------------- <<< -size: 7207 +size: 7706 location: src/tests/client/test-client.py:test_004()/779 cmd: $NMCLI --mode multiline --pretty --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 7034 bytes +stdout: 7533 bytes >>> =============================================================================== Connection profile details (con-vpn-1) @@ -45008,6 +45628,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -45030,13 +45653,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -45045,9 +45670,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -45062,6 +45690,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -45077,7 +45706,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -45123,12 +45753,12 @@ VPN.CFG[3]: key3 = val3 ------------------------------------------------------------------------------- <<< -size: 7257 +size: 7756 location: src/tests/client/test-client.py:test_004()/780 cmd: $NMCLI --mode multiline --pretty --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 7074 bytes +stdout: 7573 bytes >>> =============================================================================== Szczegóły profilu połączenia (con-vpn-1) @@ -45155,6 +45785,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -45177,13 +45810,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -45192,9 +45827,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -45209,6 +45847,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -45224,7 +45863,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -45270,12 +45910,12 @@ VPN.CFG[3]: key3 = val3 ------------------------------------------------------------------------------- <<< -size: 5688 +size: 6187 location: src/tests/client/test-client.py:test_004()/781 cmd: $NMCLI --mode multiline --pretty --color yes -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 5508 bytes +stdout: 6007 bytes >>> =============================================================================== Connection profile details (con-vpn-1) @@ -45302,6 +45942,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: unknown connection.lldp: default connection.mdns: -1 (default) @@ -45324,13 +45967,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: no ipv4.ignore-auto-dns: no ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: yes +ipv4.dhcp-send-hostname-deprecated: yes +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -45339,9 +45984,12 @@ ipv4.may-fail: yes ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -45356,6 +46004,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: no ipv6.ignore-auto-dns: no ipv6.never-default: no @@ -45371,7 +46020,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: yes +ipv6.dhcp-send-hostname-deprecated: yes +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -45391,12 +46041,12 @@ proxy.pac-script: -- ------------------------------------------------------------------------------- <<< -size: 5720 +size: 6219 location: src/tests/client/test-client.py:test_004()/782 cmd: $NMCLI --mode multiline --pretty --color yes -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 5530 bytes +stdout: 6029 bytes >>> =============================================================================== Szczegóły profilu połączenia (con-vpn-1) @@ -45423,6 +46073,9 @@ connection.autoconnect-ports: -1 (default) connection.down-on-poweroff: -1 (default) connection.secondaries: -- connection.gateway-ping-timeout: 0 +connection.ip-ping-timeout: 0 +connection.ip-ping-addresses: -- +connection.ip-ping-addresses-require-all:-1 (default) connection.metered: nieznane connection.lldp: default connection.mdns: -1 (default) @@ -45445,13 +46098,15 @@ ipv4.route-table: 0 (unspec) ipv4.routing-rules: -- ipv4.replace-local-rule: -1 (default) ipv4.dhcp-send-release: -1 (default) +ipv4.routed-dns: -1 (default) ipv4.ignore-auto-routes: nie ipv4.ignore-auto-dns: nie ipv4.dhcp-client-id: -- ipv4.dhcp-iaid: -- ipv4.dhcp-dscp: -- ipv4.dhcp-timeout: 0 (default) -ipv4.dhcp-send-hostname: tak +ipv4.dhcp-send-hostname-deprecated: tak +ipv4.dhcp-send-hostname: -1 (default) ipv4.dhcp-hostname: -- ipv4.dhcp-fqdn: -- ipv4.dhcp-hostname-flags: 0x0 (none) @@ -45460,9 +46115,12 @@ ipv4.may-fail: tak ipv4.required-timeout: -1 (default) ipv4.dad-timeout: -1 (default) ipv4.dhcp-vendor-class-identifier: -- +ipv4.dhcp-ipv6-only-preferred: -1 (default) ipv4.link-local: 0 (default) ipv4.dhcp-reject-servers: -- ipv4.auto-route-ext-gw: -1 (default) +ipv4.shared-dhcp-range: -- +ipv4.shared-dhcp-lease-time: 0 (default) ------------------------------------------------------------------------------- ipv6.method: auto ipv6.dns: -- @@ -45477,6 +46135,7 @@ ipv6.route-table: 0 (unspec) ipv6.routing-rules: -- ipv6.replace-local-rule: -1 (default) ipv6.dhcp-send-release: -1 (default) +ipv6.routed-dns: -1 (default) ipv6.ignore-auto-routes: nie ipv6.ignore-auto-dns: nie ipv6.never-default: nie @@ -45492,7 +46151,8 @@ ipv6.dhcp-pd-hint: -- ipv6.dhcp-duid: -- ipv6.dhcp-iaid: -- ipv6.dhcp-timeout: 0 (default) -ipv6.dhcp-send-hostname: tak +ipv6.dhcp-send-hostname-deprecated: tak +ipv6.dhcp-send-hostname: -1 (default) ipv6.dhcp-hostname: -- ipv6.dhcp-hostname-flags: 0x0 (none) ipv6.auto-route-ext-gw: -1 (default) @@ -49266,12 +49926,12 @@ connection.interface-name: -- ------------------------------------------------------------------------------- <<< -size: 3122 +size: 3426 location: src/tests/client/test-client.py:test_004()/827 cmd: $NMCLI --mode multiline --terse con s con-vpn-1 lang: C returncode: 0 -stdout: 2962 bytes +stdout: 3266 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -49295,6 +49955,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -49316,13 +49979,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -49331,9 +49996,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -49347,6 +50015,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -49362,7 +50031,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -49400,12 +50070,12 @@ VPN.CFG[2]:key2 = val2 VPN.CFG[3]:key3 = val3 <<< -size: 3132 +size: 3436 location: src/tests/client/test-client.py:test_004()/828 cmd: $NMCLI --mode multiline --terse con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 2962 bytes +stdout: 3266 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -49429,6 +50099,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -49450,13 +50123,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -49465,9 +50140,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -49481,6 +50159,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -49496,7 +50175,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -49534,12 +50214,12 @@ VPN.CFG[2]:key2 = val2 VPN.CFG[3]:key3 = val3 <<< -size: 3122 +size: 3426 location: src/tests/client/test-client.py:test_004()/829 cmd: $NMCLI --mode multiline --terse con s con-vpn-1 lang: C returncode: 0 -stdout: 2962 bytes +stdout: 3266 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -49563,6 +50243,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -49584,13 +50267,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -49599,9 +50284,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -49615,6 +50303,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -49630,7 +50319,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -49668,12 +50358,12 @@ VPN.CFG[2]:key2 = val2 VPN.CFG[3]:key3 = val3 <<< -size: 3132 +size: 3436 location: src/tests/client/test-client.py:test_004()/830 cmd: $NMCLI --mode multiline --terse con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 2962 bytes +stdout: 3266 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -49697,6 +50387,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -49718,13 +50411,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -49733,9 +50428,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -49749,6 +50447,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -49764,7 +50463,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -49802,12 +50502,12 @@ VPN.CFG[2]:key2 = val2 VPN.CFG[3]:key3 = val3 <<< -size: 2547 +size: 2851 location: src/tests/client/test-client.py:test_004()/831 cmd: $NMCLI --mode multiline --terse -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 2380 bytes +stdout: 2684 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -49831,6 +50531,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -49852,13 +50555,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -49867,9 +50572,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -49883,6 +50591,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -49898,7 +50607,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -49915,12 +50625,12 @@ proxy.pac-url: proxy.pac-script: <<< -size: 2557 +size: 2861 location: src/tests/client/test-client.py:test_004()/832 cmd: $NMCLI --mode multiline --terse -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 2380 bytes +stdout: 2684 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -49944,6 +50654,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -49965,13 +50678,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -49980,9 +50695,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -49996,6 +50714,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -50011,7 +50730,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -53148,12 +53868,12 @@ connection.type:802-11-wireless connection.interface-name: <<< -size: 3134 +size: 3438 location: src/tests/client/test-client.py:test_004()/877 cmd: $NMCLI --mode multiline --terse --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 2962 bytes +stdout: 3266 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -53177,6 +53897,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -53198,13 +53921,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -53213,9 +53938,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -53229,6 +53957,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -53244,7 +53973,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -53282,12 +54012,12 @@ VPN.CFG[2]:key2 = val2 VPN.CFG[3]:key3 = val3 <<< -size: 3144 +size: 3448 location: src/tests/client/test-client.py:test_004()/878 cmd: $NMCLI --mode multiline --terse --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 2962 bytes +stdout: 3266 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -53311,6 +54041,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -53332,13 +54065,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -53347,9 +54082,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -53363,6 +54101,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -53378,7 +54117,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -53416,12 +54156,12 @@ VPN.CFG[2]:key2 = val2 VPN.CFG[3]:key3 = val3 <<< -size: 3134 +size: 3438 location: src/tests/client/test-client.py:test_004()/879 cmd: $NMCLI --mode multiline --terse --color yes con s con-vpn-1 lang: C returncode: 0 -stdout: 2962 bytes +stdout: 3266 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -53445,6 +54185,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -53466,13 +54209,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -53481,9 +54226,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -53497,6 +54245,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -53512,7 +54261,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -53550,12 +54300,12 @@ VPN.CFG[2]:key2 = val2 VPN.CFG[3]:key3 = val3 <<< -size: 3144 +size: 3448 location: src/tests/client/test-client.py:test_004()/880 cmd: $NMCLI --mode multiline --terse --color yes con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 2962 bytes +stdout: 3266 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -53579,6 +54329,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -53600,13 +54353,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -53615,9 +54370,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -53631,6 +54389,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -53646,7 +54405,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -53684,12 +54444,12 @@ VPN.CFG[2]:key2 = val2 VPN.CFG[3]:key3 = val3 <<< -size: 2559 +size: 2863 location: src/tests/client/test-client.py:test_004()/881 cmd: $NMCLI --mode multiline --terse --color yes -f ALL con s con-vpn-1 lang: C returncode: 0 -stdout: 2380 bytes +stdout: 2684 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -53713,6 +54473,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -53734,13 +54497,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -53749,9 +54514,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -53765,6 +54533,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -53780,7 +54549,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 @@ -53797,12 +54567,12 @@ proxy.pac-url: proxy.pac-script: <<< -size: 2569 +size: 2873 location: src/tests/client/test-client.py:test_004()/882 cmd: $NMCLI --mode multiline --terse --color yes -f ALL con s con-vpn-1 lang: pl_PL.UTF-8 returncode: 0 -stdout: 2380 bytes +stdout: 2684 bytes >>> connection.id:con-vpn-1 connection.uuid:UUID-con-vpn-1-REPLACED-REPLACED-REP @@ -53826,6 +54596,9 @@ connection.autoconnect-ports:-1 connection.down-on-poweroff:-1 connection.secondaries: connection.gateway-ping-timeout:0 +connection.ip-ping-timeout:0 +connection.ip-ping-addresses: +connection.ip-ping-addresses-require-all:-1 connection.metered:unknown connection.lldp:default connection.mdns:-1 @@ -53847,13 +54620,15 @@ ipv4.route-table:0 ipv4.routing-rules: ipv4.replace-local-rule:-1 ipv4.dhcp-send-release:-1 +ipv4.routed-dns:-1 ipv4.ignore-auto-routes:no ipv4.ignore-auto-dns:no ipv4.dhcp-client-id: ipv4.dhcp-iaid: ipv4.dhcp-dscp: ipv4.dhcp-timeout:0 -ipv4.dhcp-send-hostname:yes +ipv4.dhcp-send-hostname-deprecated:yes +ipv4.dhcp-send-hostname:-1 ipv4.dhcp-hostname: ipv4.dhcp-fqdn: ipv4.dhcp-hostname-flags:0x0 @@ -53862,9 +54637,12 @@ ipv4.may-fail:yes ipv4.required-timeout:-1 ipv4.dad-timeout:-1 ipv4.dhcp-vendor-class-identifier: +ipv4.dhcp-ipv6-only-preferred:-1 ipv4.link-local:0 ipv4.dhcp-reject-servers: ipv4.auto-route-ext-gw:-1 +ipv4.shared-dhcp-range: +ipv4.shared-dhcp-lease-time:0 ipv6.method:auto ipv6.dns: ipv6.dns-search: @@ -53878,6 +54656,7 @@ ipv6.route-table:0 ipv6.routing-rules: ipv6.replace-local-rule:-1 ipv6.dhcp-send-release:-1 +ipv6.routed-dns:-1 ipv6.ignore-auto-routes:no ipv6.ignore-auto-dns:no ipv6.never-default:no @@ -53893,7 +54672,8 @@ ipv6.dhcp-pd-hint: ipv6.dhcp-duid: ipv6.dhcp-iaid: ipv6.dhcp-timeout:0 -ipv6.dhcp-send-hostname:yes +ipv6.dhcp-send-hostname-deprecated:yes +ipv6.dhcp-send-hostname:-1 ipv6.dhcp-hostname: ipv6.dhcp-hostname-flags:0x0 ipv6.auto-route-ext-gw:-1 diff --git a/src/tests/client/test-client.py b/src/tests/client/test-client.py index 60853e6d..d01b3bce 100755 --- a/src/tests/client/test-client.py +++ b/src/tests/client/test-client.py @@ -19,18 +19,14 @@ from __future__ import print_function # # For that, you'd setup your system correctly (see SETUP below) and then simply: # -# $ NM_TEST_REGENERATE=1 make check-local-tests-client -# # Or `NM_TEST_REGENERATE=1 make check -j 10` +# $ meson -Ddocs=true --prefix=/tmp/nm1 build +# $ ninja -C build +# $ ninja -C build install +# $ NM_TEST_REGENERATE=1 ninja -C build test # $ git diff ... ; git add ... # # The previous step regenerated the expected output. Review the changes # # and consider whether they are correct. Then commit the changes to git. # -# With meson, you can do -# $ meson -Ddocs=true --prefix=/tmp/nm1 build -# $ ninja -C build -# $ ninja -C build install -# $ NM_TEST_REGENERATE=1 ninja -C build test -# # Beware that you need to install the sources, and beware to choose a prefix that doesn't # mess up your system (see SETUP below). # @@ -52,7 +48,7 @@ from __future__ import print_function # # Ensure that the built nmcli has Polish locale working. If not, # # you probably need to first `make install` the application at the # # correct prefix. Take care to configure the build with the desired -# # prefix, like `./configure --prefix=/opt/tmp`. Usually, you want to avoid +# # prefix, like `meson setup build --prefix=/opt/tmp`. Usually, you want to avoid # # using /usr as prefix, because that might overwrite files from your # # package management system. # @@ -90,6 +86,9 @@ ENV_NM_TEST_REGENERATE = "NM_TEST_REGENERATE" # numbers enabled. ENV_NM_TEST_WITH_LINENO = "NM_TEST_WITH_LINENO" +# Log pexpect output to stderr, for debuging +ENV_NM_TEST_LOG_PEXPECT = "NM_TEST_LOG_PEXPECT" + ENV_NM_TEST_ASAN_OPTIONS = "NM_TEST_ASAN_OPTIONS" ENV_NM_TEST_LSAN_OPTIONS = "NM_TEST_LSAN_OPTIONS" ENV_NM_TEST_UBSAN_OPTIONS = "NM_TEST_UBSAN_OPTIONS" @@ -689,29 +688,6 @@ class Util: return argv, valgrind_log @staticmethod - def cmd_call_pexpect(cmd_path, args, extra_env): - argv, valgrind_log = Util.cmd_create_argv(cmd_path, args) - env = Util.cmd_create_env(extra_env=extra_env) - - pexp = pexpect.spawn(argv[0], argv[1:], timeout=10, env=env) - - pexp.str_last_chars = 100000 - - typ = collections.namedtuple("CallPexpect", ["pexp", "valgrind_log"]) - return typ(pexp, valgrind_log) - - @staticmethod - def cmd_call_pexpect_nmcli(args, extra_env={}): - extra_env = extra_env.copy() - extra_env.update({"NO_COLOR": "1"}) - - return Util.cmd_call_pexpect( - ENV_NM_TEST_CLIENT_NMCLI_PATH, - args, - extra_env, - ) - - @staticmethod def get_nmcli_version(): ver = NM.utils_version() micro = ver & 0xFF @@ -737,7 +713,7 @@ class Configuration: ) if not os.path.isdir(v): raise Exception("Missing builddir. Set NM_TEST_CLIENT_BUILDDIR?") - elif name == ENV_NM_TEST_CLIENT_NMCLI_PATH: + elif name == "ENV_NM_TEST_CLIENT_NMCLI_UNCHECKED_PATH": v = os.environ.get(ENV_NM_TEST_CLIENT_NMCLI_PATH, None) if v is None: try: @@ -746,6 +722,8 @@ class Configuration: ) except: pass + elif name == ENV_NM_TEST_CLIENT_NMCLI_PATH: + v = self.get("ENV_NM_TEST_CLIENT_NMCLI_UNCHECKED_PATH") if not os.path.exists(v): raise Exception("Missing nmcli binary. Set NM_TEST_CLIENT_NMCLI_PATH?") elif name == ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH: @@ -779,6 +757,8 @@ class Configuration: v = Util.is_bool(os.environ.get(ENV_NM_TEST_REGENERATE, None)) elif name == ENV_NM_TEST_WITH_LINENO: v = Util.is_bool(os.environ.get(ENV_NM_TEST_WITH_LINENO, None)) + elif name == ENV_NM_TEST_LOG_PEXPECT: + v = Util.is_bool(os.environ.get(ENV_NM_TEST_LOG_PEXPECT, None)) elif name == ENV_NM_TEST_VALGRIND: if self.get(ENV_NM_TEST_REGENERATE): v = False @@ -808,7 +788,7 @@ class Configuration: v = os.environ.get(name, None) if v is None: v = os.path.abspath( - os.path.dirname(self.get(ENV_NM_TEST_CLIENT_NMCLI_PATH)) + os.path.dirname(self.get("ENV_NM_TEST_CLIENT_NMCLI_UNCHECKED_PATH")) + "/../../libtool" ) if not os.path.isfile(v): @@ -1071,6 +1051,7 @@ class NMTestContext: self._calling_num = {} self._skip_test_for_l10n_diff = [] self._async_jobs = [] + self._nmc = None self.ctx_results = [] self.srv = None @@ -1129,112 +1110,60 @@ class NMTestContext: def async_append_job(self, async_job): self._async_jobs.append(async_job) - def run_post(self): - self.async_wait() + def cmd_call_pexpect(self, cmd_path, args, extra_env): + if self._nmc is not None: + raise Exception("Unfinished pexpect run exists") - self.srv_shutdown() + argv, valgrind_log = Util.cmd_create_argv(cmd_path, args) + env = Util.cmd_create_env(extra_env=extra_env) - self._calling_num = None + pexp = pexpect.spawn(argv[0], argv[1:], timeout=10, env=env, encoding="utf-8") + if conf.get(ENV_NM_TEST_LOG_PEXPECT): + pexp.logfile = sys.stderr - results = self.ctx_results - self.ctx_results = None + pexp.str_last_chars = 100000 - if len(results) == 0: - return + typ = collections.namedtuple("CallPexpect", ["pexp", "valgrind_log"]) + self._nmc = typ(pexp, valgrind_log) + return pexp - skip_test_for_l10n_diff = self._skip_test_for_l10n_diff - self._skip_test_for_l10n_diff = None + def cmd_call_pexpect_nmcli(self, args, extra_env={}): + extra_env = extra_env.copy() + extra_env.update({"NO_COLOR": "1"}) - filename = os.path.abspath( - PathConfiguration.srcdir() - + "/test-client.check-on-disk/" - + self.testMethodName - + ".expected" + return self.cmd_call_pexpect( + ENV_NM_TEST_CLIENT_NMCLI_PATH, + args, + extra_env, ) - regenerate = conf.get(ENV_NM_TEST_REGENERATE) + def cmd_close_pexpect(self, pexp=None, signal=None): + if self._nmc is None: + raise Exception("No pexpect run exists") - content_expect, results_expect = Util.file_read_expected(filename) + if signal is not None: + pexp.kill(signal) + pexp.expect(pexpect.EOF) + pexp.close() - if results_expect is None: - if not regenerate: - self.fail( - "Failed to parse expected file '%s'. Let the test write the file by rerunning with NM_TEST_REGENERATE=1" - % (filename) - ) - else: - for i in range(0, min(len(results_expect), len(results))): - n = results[i] - if results_expect[i] == n["content"]: - continue - if regenerate: - continue - if n["ignore_l10n_diff"]: - skip_test_for_l10n_diff.append(n["test_name"]) - continue - print( - "\n\n\nThe file '%s' does not have the expected content:" - % (filename) - ) - print("ACTUAL OUTPUT:\n[[%s]]\n" % (n["content"])) - print("EXPECT OUTPUT:\n[[%s]]\n" % (results_expect[i])) - print( - "Let the test write the file by rerunning with NM_TEST_REGENERATE=1" - ) - print( - "See howto in %s for details.\n" - % (PathConfiguration.canonical_script_filename()) - ) - sys.stdout.flush() - self.fail( - "Unexpected output of command, expected %s. Rerun test with NM_TEST_REGENERATE=1 to regenerate files" - % (filename) - ) - if len(results_expect) != len(results): - if not regenerate: - print( - "\n\n\nThe number of tests in %s does not match the expected content (%s vs %s):" - % (filename, len(results_expect), len(results)) - ) - if len(results_expect) < len(results): - print( - "ACTUAL OUTPUT:\n[[%s]]\n" - % (results[len(results_expect)]["content"]) - ) - else: - print( - "EXPECT OUTPUT:\n[[%s]]\n" % (results_expect[len(results)]) - ) - print( - "Let the test write the file by rerunning with NM_TEST_REGENERATE=1" - ) - print( - "See howto in %s for details.\n" - % (PathConfiguration.canonical_script_filename()) - ) - sys.stdout.flush() - self.fail( - "Unexpected output of command, expected %s. Rerun test with NM_TEST_REGENERATE=1 to regenerate files" - % (filename) - ) + valgrind_log = self._nmc.valgrind_log + self._nmc = None + return (pexp.exitstatus, pexp.signalstatus, valgrind_log) - if regenerate: - content_new = b"".join([r["content"] for r in results]) - if content_new != content_expect: - try: - with open(filename, "wb") as content_file: - content_file.write(content_new) - except Exception as e: - self.fail("Failure to write '%s': %s" % (filename, e)) + def pexpect_cleanup(self): + if self._nmc is None: + return - if skip_test_for_l10n_diff: - # nmcli loads translations from the installation path. This failure commonly - # happens because you did not install the binary in the --prefix, before - # running the test. Hence, translations are not available or differ. - raise unittest.SkipTest( - "Skipped asserting for localized tests %s. Set NM_TEST_CLIENT_CHECK_L10N=1 to force fail." - % (",".join(skip_test_for_l10n_diff)) + (exitstatus, signalstatus, _valgrind_log) = self.cmd_close_pexpect( + self._nmc.pexp + ) + if signalstatus is not None: + print( + "*** pexpect'd process killed by %s ***" + % Util.signal_no_to_str(signalstatus) ) + if exitstatus is not None: + print("*** pexpect'd process exited with status = %d ***" % exitstatus) ############################################################################### @@ -1245,6 +1174,7 @@ class TestNmcli(unittest.TestCase): Util.skip_without_dbus_session() Util.skip_without_NM() self.ctx = NMTestContext(self._testMethodName) + self._skip_test_for_l10n_diff = [] def call_nmcli_l( self, @@ -1505,18 +1435,125 @@ class TestNmcli(unittest.TestCase): self.ctx.async_start(wait_all=sync_barrier) + def run_post(self): + self.ctx.async_wait() + self.ctx.srv_shutdown() + self.ctx.pexpect_cleanup() + + self.ctx._calling_num = None + + results = self.ctx.ctx_results + self.ctx.ctx_results = None + + if len(results) == 0: + return + + skip_test_for_l10n_diff = self._skip_test_for_l10n_diff + self._skip_test_for_l10n_diff = None + + filename = os.path.abspath( + PathConfiguration.srcdir() + + "/test-client.check-on-disk/" + + self._testMethodName + + ".expected" + ) + + regenerate = conf.get(ENV_NM_TEST_REGENERATE) + + content_expect, results_expect = Util.file_read_expected(filename) + + if results_expect is None: + if not regenerate: + self.fail( + "Failed to parse expected file '%s'. Let the test write the file by rerunning with NM_TEST_REGENERATE=1" + % (filename) + ) + else: + for i in range(0, min(len(results_expect), len(results))): + n = results[i] + if results_expect[i] == n["content"]: + continue + if regenerate: + continue + if n["ignore_l10n_diff"]: + skip_test_for_l10n_diff.append(n["test_name"]) + continue + print( + "\n\n\nThe file '%s' does not have the expected content:" + % (filename) + ) + print("ACTUAL OUTPUT:\n[[%s]]\n" % (n["content"])) + print("EXPECT OUTPUT:\n[[%s]]\n" % (results_expect[i])) + print( + "Let the test write the file by rerunning with NM_TEST_REGENERATE=1" + ) + print( + "See howto in %s for details.\n" + % (PathConfiguration.canonical_script_filename()) + ) + sys.stdout.flush() + self.fail( + "Unexpected output of command, expected %s. Rerun test with NM_TEST_REGENERATE=1 to regenerate files" + % (filename) + ) + if len(results_expect) != len(results): + if not regenerate: + print( + "\n\n\nThe number of tests in %s does not match the expected content (%s vs %s):" + % (filename, len(results_expect), len(results)) + ) + if len(results_expect) < len(results): + print( + "ACTUAL OUTPUT:\n[[%s]]\n" + % (results[len(results_expect)]["content"]) + ) + else: + print( + "EXPECT OUTPUT:\n[[%s]]\n" % (results_expect[len(results)]) + ) + print( + "Let the test write the file by rerunning with NM_TEST_REGENERATE=1" + ) + print( + "See howto in %s for details.\n" + % (PathConfiguration.canonical_script_filename()) + ) + sys.stdout.flush() + self.fail( + "Unexpected output of command, expected %s. Rerun test with NM_TEST_REGENERATE=1 to regenerate files" + % (filename) + ) + + if regenerate: + content_new = b"".join([r["content"] for r in results]) + if content_new != content_expect: + try: + with open(filename, "wb") as content_file: + content_file.write(content_new) + except Exception as e: + self.fail("Failure to write '%s': %s" % (filename, e)) + + if skip_test_for_l10n_diff: + # nmcli loads translations from the installation path. This failure commonly + # happens because you did not install the binary in the --prefix, before + # running the test. Hence, translations are not available or differ. + raise unittest.SkipTest( + "Skipped asserting for localized tests %s. Set NM_TEST_CLIENT_CHECK_L10N=1 to force fail." + % (",".join(skip_test_for_l10n_diff)) + ) + def nm_test(func): def f(self): self.ctx.srv_start() func(self) - self.ctx.run_post() + self.run_post() return f def nm_test_no_dbus(func): def f(self): func(self) - self.ctx.run_post() + self.run_post() return f @@ -2188,26 +2225,31 @@ class TestNmcli(unittest.TestCase): @Util.skip_without_pexpect @nm_test def test_ask_mode(self): - nmc = Util.cmd_call_pexpect_nmcli(["--ask", "c", "add"]) - nmc.pexp.expect("Connection type:") - nmc.pexp.sendline("ethernet") - nmc.pexp.expect("Interface name:") - nmc.pexp.sendline("eth0") - nmc.pexp.expect("There are 3 optional settings for Wired Ethernet.") - nmc.pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") - nmc.pexp.sendline("no") - nmc.pexp.expect("There are 2 optional settings for IPv4 protocol.") - nmc.pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") - nmc.pexp.sendline("no") - nmc.pexp.expect("There are 2 optional settings for IPv6 protocol.") - nmc.pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") - nmc.pexp.sendline("no") - nmc.pexp.expect("There are 4 optional settings for Proxy.") - nmc.pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") - nmc.pexp.sendline("no") - nmc.pexp.expect(r"Connection 'ethernet' \(.*\) successfully added.") - nmc.pexp.expect(pexpect.EOF) - Util.valgrind_check_log(nmc.valgrind_log, "test_ask_mode") + pexp = self.ctx.cmd_call_pexpect_nmcli(["--ask", "c", "add"]) + pexp.expect("Connection type:") + pexp.sendline("ethernet") + pexp.expect("Interface name:") + pexp.sendline("eth0") + pexp.expect("There are 3 optional settings for Wired Ethernet.") + pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") + pexp.sendline("no") + pexp.expect("There are 2 optional settings for IPv4 protocol.") + pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") + pexp.sendline("no") + pexp.expect("There are 2 optional settings for IPv6 protocol.") + pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") + pexp.sendline("no") + pexp.expect("There are 4 optional settings for Proxy.") + pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") + pexp.sendline("no") + pexp.expect(r"Connection 'ethernet' \(.*\) successfully added.") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_ask_mode") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") @Util.skip_without_pexpect @nm_test @@ -2218,26 +2260,26 @@ class TestNmcli(unittest.TestCase): "DBUS_SESSION_BUS_ADDRESS": "very:invalid", } - nmc = Util.cmd_call_pexpect_nmcli( + pexp = self.ctx.cmd_call_pexpect_nmcli( ["--offline", "--ask", "c", "add"], extra_env=no_dbus_env ) - nmc.pexp.expect("Connection type:") - nmc.pexp.sendline("ethernet") - nmc.pexp.expect("Interface name:") - nmc.pexp.sendline("eth0") - nmc.pexp.expect("There are 3 optional settings for Wired Ethernet.") - nmc.pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") - nmc.pexp.sendline("no") - nmc.pexp.expect("There are 2 optional settings for IPv4 protocol.") - nmc.pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") - nmc.pexp.sendline("no") - nmc.pexp.expect("There are 2 optional settings for IPv6 protocol.") - nmc.pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") - nmc.pexp.sendline("no") - nmc.pexp.expect("There are 4 optional settings for Proxy.") - nmc.pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") - nmc.pexp.sendline("no") - nmc.pexp.expect( + pexp.expect("Connection type:") + pexp.sendline("ethernet") + pexp.expect("Interface name:") + pexp.sendline("eth0") + pexp.expect("There are 3 optional settings for Wired Ethernet.") + pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") + pexp.sendline("no") + pexp.expect("There are 2 optional settings for IPv4 protocol.") + pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") + pexp.sendline("no") + pexp.expect("There are 2 optional settings for IPv6 protocol.") + pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") + pexp.sendline("no") + pexp.expect("There are 4 optional settings for Proxy.") + pexp.expect(r"Do you want to provide them\? \(yes/no\) \[yes]") + pexp.sendline("no") + pexp.expect( r"\[connection\]\r\n" r"id=ethernet\r\n" r"uuid=.*\r\n" @@ -2255,43 +2297,58 @@ class TestNmcli(unittest.TestCase): r"\r\n" r"\[proxy\]\r\n" ) - nmc.pexp.expect(pexpect.EOF) - Util.valgrind_check_log(nmc.valgrind_log, "test_ask_offline") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_ask_offline") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") @Util.skip_without_pexpect @nm_test def test_monitor(self): def start_mon(self): - nmc = Util.cmd_call_pexpect_nmcli(["monitor"]) - nmc.pexp.expect("NetworkManager is running") - return nmc + pexp = self.ctx.cmd_call_pexpect_nmcli(["monitor"]) + pexp.expect("NetworkManager is running") + return pexp - def end_mon(self, nmc): - nmc.pexp.kill(signal.SIGINT) - nmc.pexp.expect(pexpect.EOF) - Util.valgrind_check_log(nmc.valgrind_log, "test_monitor") + def end_mon(self, pexp): + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect( + pexp, signal=signal.SIGINT + ) + Util.valgrind_check_log(valgrind_log, "test_monitor") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual( + exitstatus, + 128 + signal.SIGINT, + "Unexpectedly returned a non-zero status", + ) - nmc = start_mon(self) + pexp = start_mon(self) self.ctx.srv.op_AddObj("WiredDevice", iface="eth0") - nmc.pexp.expect("eth0: device created\r\n") + pexp.expect("eth0: device created\r\n") self.ctx.srv.addConnection( {"connection": {"type": "802-3-ethernet", "id": "con-1"}} ) - nmc.pexp.expect("con-1: connection profile created\r\n") + pexp.expect("con-1: connection profile created\r\n") - end_mon(self, nmc) + end_mon(self, pexp) - nmc = start_mon(self) + pexp = start_mon(self) self.ctx.srv_shutdown() Util.pexpect_expect_all( - nmc.pexp, + pexp, "con-1: connection profile removed", "eth0: device removed", ) - nmc.pexp.expect("NetworkManager is stopped") - end_mon(self, nmc) + pexp.expect("NetworkManager is stopped") + end_mon(self, pexp) @nm_test_no_dbus # we need dbus, but we need to pass arguments to srv_start def test_version_warn(self): @@ -2373,7 +2430,9 @@ class TestNmCloudSetup(unittest.TestCase): func(self) except Exception as e: error = e - self.ctx.run_post() + self.ctx.async_wait() + self.ctx.srv_shutdown() + self.ctx.pexpect_cleanup() self.md_conn.close() p.stdin.close() @@ -2456,7 +2515,8 @@ class TestNmCloudSetup(unittest.TestCase): ) # Run nm-cloud-setup for the first time - nmc = Util.cmd_call_pexpect( + + pexp = self.ctx.cmd_call_pexpect( ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, [], { @@ -2466,19 +2526,25 @@ class TestNmCloudSetup(unittest.TestCase): }, ) - nmc.pexp.expect("provider aliyun detected") - nmc.pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") - nmc.pexp.expect("get-config: start fetching meta data") - nmc.pexp.expect("get-config: success") - nmc.pexp.expect("meta data received") + pexp.expect("provider aliyun detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("get-config: start fetching meta data") + pexp.expect("get-config: success") + pexp.expect("meta data received") # One of the devices has no IPv4 configuration to be modified - nmc.pexp.expect("device has no suitable applied connection. Skip") + pexp.expect("device has no suitable applied connection. Skip") # The other one was lacking an address set it up. - nmc.pexp.expect("some changes were applied for provider aliyun") - nmc.pexp.expect(pexpect.EOF) + pexp.expect("some changes were applied for provider aliyun") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_aliyun") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") # Run nm-cloud-setup for the second time - nmc = Util.cmd_call_pexpect( + pexp = self.ctx.cmd_call_pexpect( ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, [], { @@ -2488,17 +2554,21 @@ class TestNmCloudSetup(unittest.TestCase): }, ) - nmc.pexp.expect("provider aliyun detected") - nmc.pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") - nmc.pexp.expect("get-config: starting") - nmc.pexp.expect("get-config: success") - nmc.pexp.expect("meta data received") + pexp.expect("provider aliyun detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("get-config: starting") + pexp.expect("get-config: success") + pexp.expect("meta data received") # No changes this time - nmc.pexp.expect('device needs no update to applied connection "con-eth0"') - nmc.pexp.expect("no changes were applied for provider aliyun") - nmc.pexp.expect(pexpect.EOF) - - Util.valgrind_check_log(nmc.valgrind_log, "test_aliyun") + pexp.expect('device needs no update to applied connection "con-eth0"') + pexp.expect("no changes were applied for provider aliyun") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_aliyun") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") @cloud_setup_test def test_azure(self): @@ -2535,7 +2605,7 @@ class TestNmCloudSetup(unittest.TestCase): self._mock_path(_azure_iface + "1/ipv4/subnet/0/prefix/" + _azure_query, "20") # Run nm-cloud-setup for the first time - nmc = Util.cmd_call_pexpect( + pexp = self.ctx.cmd_call_pexpect( ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, [], { @@ -2545,26 +2615,32 @@ class TestNmCloudSetup(unittest.TestCase): }, ) - nmc.pexp.expect("provider azure detected") - nmc.pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") - nmc.pexp.expect("found azure interfaces: 2") - nmc.pexp.expect(r"interface\[0]: found a matching device with hwaddr") - nmc.pexp.expect( + pexp.expect("provider azure detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("found azure interfaces: 2") + pexp.expect(r"interface\[0]: found a matching device with hwaddr") + pexp.expect( r"interface\[0]: (received subnet address|received subnet prefix 20)" ) - nmc.pexp.expect( + pexp.expect( r"interface\[0]: (received subnet address|received subnet prefix 20)" ) - nmc.pexp.expect("get-config: success") - nmc.pexp.expect("meta data received") + pexp.expect("get-config: success") + pexp.expect("meta data received") # One of the devices has no IPv4 configuration to be modified - nmc.pexp.expect("device has no suitable applied connection. Skip") + pexp.expect("device has no suitable applied connection. Skip") # The other one was lacking an address set it up. - nmc.pexp.expect("some changes were applied for provider azure") - nmc.pexp.expect(pexpect.EOF) + pexp.expect("some changes were applied for provider azure") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_azure") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") # Run nm-cloud-setup for the second time - nmc = Util.cmd_call_pexpect( + pexp = self.ctx.cmd_call_pexpect( ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, [], { @@ -2574,17 +2650,21 @@ class TestNmCloudSetup(unittest.TestCase): }, ) - nmc.pexp.expect("provider azure detected") - nmc.pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") - nmc.pexp.expect("get-config: starting") - nmc.pexp.expect("get-config: success") - nmc.pexp.expect("meta data received") + pexp.expect("provider azure detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("get-config: starting") + pexp.expect("get-config: success") + pexp.expect("meta data received") # No changes this time - nmc.pexp.expect('device needs no update to applied connection "con-eth0"') - nmc.pexp.expect("no changes were applied for provider azure") - nmc.pexp.expect(pexpect.EOF) - - Util.valgrind_check_log(nmc.valgrind_log, "test_azure") + pexp.expect('device needs no update to applied connection "con-eth0"') + pexp.expect("no changes were applied for provider azure") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_azure") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") @cloud_setup_test def test_ec2(self): @@ -2611,7 +2691,7 @@ class TestNmCloudSetup(unittest.TestCase): ) # Run nm-cloud-setup for the first time - nmc = Util.cmd_call_pexpect( + pexp = self.ctx.cmd_call_pexpect( ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, [], { @@ -2621,19 +2701,25 @@ class TestNmCloudSetup(unittest.TestCase): }, ) - nmc.pexp.expect("provider ec2 detected") - nmc.pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") - nmc.pexp.expect("get-config: starting") - nmc.pexp.expect("get-config: success") - nmc.pexp.expect("meta data received") + pexp.expect("provider ec2 detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("get-config: starting") + pexp.expect("get-config: success") + pexp.expect("meta data received") # One of the devices has no IPv4 configuration to be modified - nmc.pexp.expect("device has no suitable applied connection. Skip") + pexp.expect("device has no suitable applied connection. Skip") # The other one was lacking an address set it up. - nmc.pexp.expect("some changes were applied for provider ec2") - nmc.pexp.expect(pexpect.EOF) + pexp.expect("some changes were applied for provider ec2") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_ec2") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") # Run nm-cloud-setup for the second time - nmc = Util.cmd_call_pexpect( + pexp = self.ctx.cmd_call_pexpect( ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, [], { @@ -2643,17 +2729,21 @@ class TestNmCloudSetup(unittest.TestCase): }, ) - nmc.pexp.expect("provider ec2 detected") - nmc.pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") - nmc.pexp.expect("get-config: starting") - nmc.pexp.expect("get-config: success") - nmc.pexp.expect("meta data received") + pexp.expect("provider ec2 detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("get-config: starting") + pexp.expect("get-config: success") + pexp.expect("meta data received") # No changes this time - nmc.pexp.expect('device needs no update to applied connection "con-eth0"') - nmc.pexp.expect("no changes were applied for provider ec2") - nmc.pexp.expect(pexpect.EOF) - - Util.valgrind_check_log(nmc.valgrind_log, "test_ec2") + pexp.expect('device needs no update to applied connection "con-eth0"') + pexp.expect("no changes were applied for provider ec2") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_ec2") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") @cloud_setup_test def test_gcp(self): @@ -2671,7 +2761,7 @@ class TestNmCloudSetup(unittest.TestCase): self._mock_path(gcp_iface + "1/forwarded-ips/0", TestNmCloudSetup._ip2) # Run nm-cloud-setup for the first time - nmc = Util.cmd_call_pexpect( + pexp = self.ctx.cmd_call_pexpect( ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, [], { @@ -2681,20 +2771,26 @@ class TestNmCloudSetup(unittest.TestCase): }, ) - nmc.pexp.expect("provider GCP detected") - nmc.pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") - nmc.pexp.expect("found GCP interfaces: 2") - nmc.pexp.expect(r"GCP interface\[0]: found a requested device with hwaddr") - nmc.pexp.expect("get-config: success") - nmc.pexp.expect("meta data received") + pexp.expect("provider GCP detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("found GCP interfaces: 2") + pexp.expect(r"GCP interface\[0]: found a requested device with hwaddr") + pexp.expect("get-config: success") + pexp.expect("meta data received") # One of the devices has no IPv4 configuration to be modified - nmc.pexp.expect("device has no suitable applied connection. Skip") + pexp.expect("device has no suitable applied connection. Skip") # The other one was lacking an address set it up. - nmc.pexp.expect("some changes were applied for provider GCP") - nmc.pexp.expect(pexpect.EOF) + pexp.expect("some changes were applied for provider GCP") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_gcp") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") # Run nm-cloud-setup for the second time - nmc = Util.cmd_call_pexpect( + pexp = self.ctx.cmd_call_pexpect( ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, [], { @@ -2704,17 +2800,112 @@ class TestNmCloudSetup(unittest.TestCase): }, ) - nmc.pexp.expect("provider GCP detected") - nmc.pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") - nmc.pexp.expect("get-config: starting") - nmc.pexp.expect("get-config: success") - nmc.pexp.expect("meta data received") + pexp.expect("provider GCP detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("get-config: starting") + pexp.expect("get-config: success") + pexp.expect("meta data received") # No changes this time - nmc.pexp.expect('device needs no update to applied connection "con-eth0"') - nmc.pexp.expect("no changes were applied for provider GCP") - nmc.pexp.expect(pexpect.EOF) + pexp.expect('device needs no update to applied connection "con-eth0"') + pexp.expect("no changes were applied for provider GCP") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_gcp") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") - Util.valgrind_check_log(nmc.valgrind_log, "test_gcp") + @cloud_setup_test + def test_oci(self): + self._mock_devices() + + oci_meta = "/opc/v2/" + self._mock_path(oci_meta + "instance", "{}") + self._mock_path( + oci_meta + "vnics", + """ + [ + { + "macAddr": "%s", + "privateIp": "%s", + "subnetCidrBlock": "172.31.16.0/20", + "virtualRouterIp": "172.31.16.1", + "vlanTag": 810, + "vnicId": "ocid1.vnic.oc1.cz-adamov1.foobarbaz" + }, + { + "macAddr": "%s", + "privateIp": "%s", + "subnetCidrBlock": "172.31.166.0/20", + "virtualRouterIp": "172.31.166.1", + "vlanTag": 700, + "vnicId": "ocid1.vnic.oc1.uk-hogwarts.expelliarmus" + } + ] + """ + % ( + TestNmCloudSetup._mac1, + TestNmCloudSetup._ip1, + TestNmCloudSetup._mac2, + TestNmCloudSetup._ip2, + ), + ) + + # Run nm-cloud-setup for the first time + pexp = self.ctx.cmd_call_pexpect( + ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, + [], + { + "NM_CLOUD_SETUP_OCI_HOST": self.md_url, + "NM_CLOUD_SETUP_LOG": "trace", + "NM_CLOUD_SETUP_OCI": "yes", + }, + ) + + pexp.expect("provider oci detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("get-config: starting") + pexp.expect("get-config: success") + pexp.expect("meta data received") + # One of the devices has no IPv4 configuration to be modified + pexp.expect("device has no suitable applied connection. Skip") + # The other one was lacking an address set it up. + pexp.expect("some changes were applied for provider oci") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_oci") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") + + # Run nm-cloud-setup for the second time + pexp = self.ctx.cmd_call_pexpect( + ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH, + [], + { + "NM_CLOUD_SETUP_OCI_HOST": self.md_url, + "NM_CLOUD_SETUP_LOG": "trace", + "NM_CLOUD_SETUP_OCI": "yes", + }, + ) + + pexp.expect("provider oci detected") + pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02") + pexp.expect("get-config: starting") + pexp.expect("get-config: success") + pexp.expect("meta data received") + # No changes this time + pexp.expect('device needs no update to applied connection "con-eth0"') + pexp.expect("no changes were applied for provider oci") + (exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp) + Util.valgrind_check_log(valgrind_log, "test_oci") + self.assertIsNone( + signalstatus, + "Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0), + ) + self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status") ############################################################################### |