/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * Copyright (C) 2007 - 2014 Red Hat, Inc. * Copyright (C) 2007 - 2008 Novell, Inc. */ #include "nm-default.h" #include "nm-setting-wired.h" #include #include "nm-utils.h" #include "nm-libnm-core-intern/nm-common-macros.h" #include "nm-utils-private.h" #include "nm-setting-private.h" /** * SECTION:nm-setting-wired * @short_description: Describes connection properties for Ethernet-based networks * * The #NMSettingWired object is a #NMSetting subclass that describes properties * necessary for connection to Ethernet networks. **/ /*****************************************************************************/ G_STATIC_ASSERT(NM_SETTING_WIRED_WAKE_ON_LAN_EXCLUSIVE_FLAGS == (NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT | NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE)); /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE(NMSettingWired, PROP_PORT, PROP_SPEED, PROP_DUPLEX, PROP_AUTO_NEGOTIATE, PROP_MAC_ADDRESS, PROP_CLONED_MAC_ADDRESS, PROP_GENERATE_MAC_ADDRESS_MASK, PROP_MAC_ADDRESS_BLACKLIST, PROP_MTU, PROP_S390_SUBCHANNELS, PROP_S390_NETTYPE, PROP_S390_OPTIONS, PROP_WAKE_ON_LAN, PROP_WAKE_ON_LAN_PASSWORD, ); typedef struct { struct { NMUtilsNamedValue *arr; guint len; guint n_alloc; } s390_options; GArray * mac_address_blacklist; char ** s390_subchannels; char * port; char * duplex; char * device_mac_address; char * cloned_mac_address; char * generate_mac_address_mask; char * s390_nettype; char * wol_password; NMSettingWiredWakeOnLan wol; guint32 speed; guint32 mtu; bool auto_negotiate : 1; } NMSettingWiredPrivate; G_DEFINE_TYPE(NMSettingWired, nm_setting_wired, NM_TYPE_SETTING) #define NM_SETTING_WIRED_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_WIRED, NMSettingWiredPrivate)) /*****************************************************************************/ static const char *valid_s390_opts[] = { "broadcast_mode", "buffer_count", "canonical_macaddr", "checksumming", "ctcprot", "fake_broadcast", "inter", "inter_jumbo", "ipato_add4", "ipato_add6", "ipato_enable", "ipato_invert4", "ipato_invert6", "isolation", "lancmd_timeout", "large_send", "layer2", "portname", "portno", "priority_queueing", "protocol", "route4", "route6", "rxip_add4", "rxip_add6", "sniffer", "total", "vipa_add4", "vipa_add6", NULL, }; static gboolean valid_s390_opts_check(const char *option) { #if NM_MORE_ASSERTS > 5 nm_assert(NM_PTRARRAY_LEN(valid_s390_opts) + 1 == G_N_ELEMENTS(valid_s390_opts)); { gsize i; for (i = 0; i < G_N_ELEMENTS(valid_s390_opts); i++) { if (i == G_N_ELEMENTS(valid_s390_opts) - 1) nm_assert(!valid_s390_opts[i]); else { nm_assert(valid_s390_opts[i]); nm_assert(valid_s390_opts[i][0] != '\0'); if (i > 0) g_assert(strcmp(valid_s390_opts[i - 1], valid_s390_opts[i]) < 0); } } } #endif return option && (nm_utils_array_find_binary_search(valid_s390_opts, sizeof(const char *), G_N_ELEMENTS(valid_s390_opts) - 1, &option, nm_strcmp_p_with_data, NULL) >= 0); } /** * nm_setting_wired_get_port: * @setting: the #NMSettingWired * * Returns: the #NMSettingWired:port property of the setting **/ const char * nm_setting_wired_get_port(NMSettingWired *setting) { g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); return NM_SETTING_WIRED_GET_PRIVATE(setting)->port; } /** * nm_setting_wired_get_speed: * @setting: the #NMSettingWired * * Returns: the #NMSettingWired:speed property of the setting **/ guint32 nm_setting_wired_get_speed(NMSettingWired *setting) { g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), 0); return NM_SETTING_WIRED_GET_PRIVATE(setting)->speed; } /** * nm_setting_wired_get_duplex: * @setting: the #NMSettingWired * * Returns: the #NMSettingWired:duplex property of the setting **/ const char * nm_setting_wired_get_duplex(NMSettingWired *setting) { g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); return NM_SETTING_WIRED_GET_PRIVATE(setting)->duplex; } /** * nm_setting_wired_get_auto_negotiate: * @setting: the #NMSettingWired * * Returns: the #NMSettingWired:auto-negotiate property of the setting **/ gboolean nm_setting_wired_get_auto_negotiate(NMSettingWired *setting) { g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), FALSE); return NM_SETTING_WIRED_GET_PRIVATE(setting)->auto_negotiate; } /** * nm_setting_wired_get_mac_address: * @setting: the #NMSettingWired * * Returns: the #NMSettingWired:mac-address property of the setting **/ const char * nm_setting_wired_get_mac_address(NMSettingWired *setting) { g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); return NM_SETTING_WIRED_GET_PRIVATE(setting)->device_mac_address; } /** * nm_setting_wired_get_cloned_mac_address: * @setting: the #NMSettingWired * * Returns: the #NMSettingWired:cloned-mac-address property of the setting **/ const char * nm_setting_wired_get_cloned_mac_address(NMSettingWired *setting) { g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); return NM_SETTING_WIRED_GET_PRIVATE(setting)->cloned_mac_address; } /** * nm_setting_wired_get_generate_mac_address_mask: * @setting: the #NMSettingWired * * Returns: the #NMSettingWired:generate-mac-address-mask property of the setting * * Since: 1.4 **/ const char * nm_setting_wired_get_generate_mac_address_mask(NMSettingWired *setting) { g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); return NM_SETTING_WIRED_GET_PRIVATE(setting)->generate_mac_address_mask; } /** * nm_setting_wired_get_mac_address_blacklist: * @setting: the #NMSettingWired * * Returns: the #NMSettingWired:mac-address-blacklist property of the setting **/ const char *const * nm_setting_wired_get_mac_address_blacklist(NMSettingWired *setting) { NMSettingWiredPrivate *priv; g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); priv = NM_SETTING_WIRED_GET_PRIVATE(setting); return (const char *const *) priv->mac_address_blacklist->data; } /** * nm_setting_wired_get_num_mac_blacklist_items: * @setting: the #NMSettingWired * * Returns: the number of blacklisted MAC addresses **/ guint32 nm_setting_wired_get_num_mac_blacklist_items(NMSettingWired *setting) { g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), 0); return NM_SETTING_WIRED_GET_PRIVATE(setting)->mac_address_blacklist->len; } /** * nm_setting_wired_get_mac_blacklist_item: * @setting: the #NMSettingWired * @idx: the zero-based index of the MAC address entry * * Returns: the blacklisted MAC address string (hex-digits-and-colons notation) * at index @idx **/ const char * nm_setting_wired_get_mac_blacklist_item(NMSettingWired *setting, guint32 idx) { NMSettingWiredPrivate *priv; g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); priv = NM_SETTING_WIRED_GET_PRIVATE(setting); g_return_val_if_fail(idx <= priv->mac_address_blacklist->len, NULL); return g_array_index(priv->mac_address_blacklist, const char *, idx); } /** * nm_setting_wired_add_mac_blacklist_item: * @setting: the #NMSettingWired * @mac: the MAC address string (hex-digits-and-colons notation) to blacklist * * Adds a new MAC address to the #NMSettingWired:mac-address-blacklist property. * * Returns: %TRUE if the MAC address was added; %FALSE if the MAC address * is invalid or was already present **/ gboolean nm_setting_wired_add_mac_blacklist_item(NMSettingWired *setting, const char *mac) { NMSettingWiredPrivate *priv; const char * candidate; int i; g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), FALSE); g_return_val_if_fail(mac != NULL, FALSE); if (!nm_utils_hwaddr_valid(mac, ETH_ALEN)) return FALSE; priv = NM_SETTING_WIRED_GET_PRIVATE(setting); for (i = 0; i < priv->mac_address_blacklist->len; i++) { candidate = g_array_index(priv->mac_address_blacklist, char *, i); if (nm_utils_hwaddr_matches(mac, -1, candidate, -1)) return FALSE; } mac = nm_utils_hwaddr_canonical(mac, ETH_ALEN); g_array_append_val(priv->mac_address_blacklist, mac); _notify(setting, PROP_MAC_ADDRESS_BLACKLIST); return TRUE; } /** * nm_setting_wired_remove_mac_blacklist_item: * @setting: the #NMSettingWired * @idx: index number of the MAC address * * Removes the MAC address at index @idx from the blacklist. **/ void nm_setting_wired_remove_mac_blacklist_item(NMSettingWired *setting, guint32 idx) { NMSettingWiredPrivate *priv; g_return_if_fail(NM_IS_SETTING_WIRED(setting)); priv = NM_SETTING_WIRED_GET_PRIVATE(setting); g_return_if_fail(idx < priv->mac_address_blacklist->len); g_array_remove_index(priv->mac_address_blacklist, idx); _notify(setting, PROP_MAC_ADDRESS_BLACKLIST); } /** * nm_setting_wired_remove_mac_blacklist_item_by_value: * @setting: the #NMSettingWired * @mac: the MAC address string (hex-digits-and-colons notation) to remove from * the blacklist * * Removes the MAC address @mac from the blacklist. * * Returns: %TRUE if the MAC address was found and removed; %FALSE if it was not. **/ gboolean nm_setting_wired_remove_mac_blacklist_item_by_value(NMSettingWired *setting, const char *mac) { NMSettingWiredPrivate *priv; const char * candidate; int i; g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), FALSE); g_return_val_if_fail(mac != NULL, FALSE); priv = NM_SETTING_WIRED_GET_PRIVATE(setting); for (i = 0; i < priv->mac_address_blacklist->len; i++) { candidate = g_array_index(priv->mac_address_blacklist, char *, i); if (!nm_utils_hwaddr_matches(mac, -1, candidate, -1)) { g_array_remove_index(priv->mac_address_blacklist, i); _notify(setting, PROP_MAC_ADDRESS_BLACKLIST); return TRUE; } } return FALSE; } /** * nm_setting_wired_clear_mac_blacklist_items: * @setting: the #NMSettingWired * * Removes all blacklisted MAC addresses. **/ void nm_setting_wired_clear_mac_blacklist_items(NMSettingWired *setting) { g_return_if_fail(NM_IS_SETTING_WIRED(setting)); g_array_set_size(NM_SETTING_WIRED_GET_PRIVATE(setting)->mac_address_blacklist, 0); _notify(setting, PROP_MAC_ADDRESS_BLACKLIST); } /** * nm_setting_wired_get_mtu: * @setting: the #NMSettingWired * * Returns: the #NMSettingWired:mtu property of the setting **/ guint32 nm_setting_wired_get_mtu(NMSettingWired *setting) { g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), 0); return NM_SETTING_WIRED_GET_PRIVATE(setting)->mtu; } /** * nm_setting_wired_get_s390_subchannels: * @setting: the #NMSettingWired * * Return the list of s390 subchannels that identify the device that this * connection is applicable to. The connection should only be used in * conjunction with that device. * * Returns: (transfer none) (element-type utf8): array of strings, each specifying * one subchannel the s390 device uses to communicate to the host. **/ const char *const * nm_setting_wired_get_s390_subchannels(NMSettingWired *setting) { g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); return (const char *const *) NM_SETTING_WIRED_GET_PRIVATE(setting)->s390_subchannels; } /** * nm_setting_wired_get_s390_nettype: * @setting: the #NMSettingWired * * Returns the s390 device type this connection should apply to. Will be one * of 'qeth', 'lcs', or 'ctc'. * * Returns: the s390 device type **/ const char * nm_setting_wired_get_s390_nettype(NMSettingWired *setting) { g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); return NM_SETTING_WIRED_GET_PRIVATE(setting)->s390_nettype; } /** * nm_setting_wired_get_num_s390_options: * @setting: the #NMSettingWired * * Returns the number of s390-specific options that should be set for this * device when it is activated. This can be used to retrieve each s390 * option individually using nm_setting_wired_get_s390_option(). * * Returns: the number of s390-specific device options **/ guint32 nm_setting_wired_get_num_s390_options(NMSettingWired *setting) { g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), 0); return NM_SETTING_WIRED_GET_PRIVATE(setting)->s390_options.len; } /** * nm_setting_wired_get_s390_option: * @setting: the #NMSettingWired * @idx: index of the desired option, from 0 to * nm_setting_wired_get_num_s390_options() - 1 * @out_key: (out) (transfer none): on return, the key name of the s390 specific * option; this value is owned by the setting and should not be modified * @out_value: (out) (transfer none): on return, the value of the key of the * s390 specific option; this value is owned by the setting and should not be * modified * * Given an index, return the value of the s390 option at that index. indexes * are *not* guaranteed to be static across modifications to options done by * nm_setting_wired_add_s390_option() and nm_setting_wired_remove_s390_option(), * and should not be used to refer to options except for short periods of time * such as during option iteration. * * Returns: %TRUE on success if the index was valid and an option was found, * %FALSE if the index was invalid (ie, greater than the number of options * currently held by the setting) **/ gboolean nm_setting_wired_get_s390_option(NMSettingWired *setting, guint32 idx, const char ** out_key, const char ** out_value) { NMSettingWiredPrivate *priv; /* with LTO and optimization, the compiler complains that the * output variables are not initialized. In practice, the function * only sets the output on success. But make the compiler happy. */ NM_SET_OUT(out_key, NULL); NM_SET_OUT(out_value, NULL); g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), FALSE); priv = NM_SETTING_WIRED_GET_PRIVATE(setting); g_return_val_if_fail(idx < priv->s390_options.len, FALSE); NM_SET_OUT(out_key, priv->s390_options.arr[idx].name); NM_SET_OUT(out_value, priv->s390_options.arr[idx].value_str); return TRUE; } /** * nm_setting_wired_get_s390_option_by_key: * @setting: the #NMSettingWired * @key: the key for which to retrieve the value * * Returns the value associated with the s390-specific option specified by * @key, if it exists. * * Returns: the value, or %NULL if the key/value pair was never added to the * setting; the value is owned by the setting and must not be modified **/ const char * nm_setting_wired_get_s390_option_by_key(NMSettingWired *setting, const char *key) { NMSettingWiredPrivate *priv; gssize idx; g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); g_return_val_if_fail(key && key[0], NULL); priv = NM_SETTING_WIRED_GET_PRIVATE(setting); idx = nm_utils_named_value_list_find(priv->s390_options.arr, priv->s390_options.len, key, TRUE); if (idx < 0) return NULL; return priv->s390_options.arr[idx].value_str; } /** * nm_setting_wired_add_s390_option: * @setting: the #NMSettingWired * @key: key name for the option * @value: value for the option * * Add an option to the table. The option is compared to an internal list * of allowed options. Key names may contain only alphanumeric characters * (ie [a-zA-Z0-9]). Adding a new key replaces any existing key/value pair that * may already exist. * * Returns: %TRUE if the option was valid and was added to the internal option * list, %FALSE if it was not. **/ gboolean nm_setting_wired_add_s390_option(NMSettingWired *setting, const char *key, const char *value) { NMSettingWiredPrivate *priv; gssize idx; NMUtilsNamedValue * v; g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), FALSE); g_return_val_if_fail(value, FALSE); if (!valid_s390_opts_check(key)) { g_return_val_if_fail(key, FALSE); return FALSE; } priv = NM_SETTING_WIRED_GET_PRIVATE(setting); idx = nm_utils_named_value_list_find(priv->s390_options.arr, priv->s390_options.len, key, TRUE); if (idx < 0) { gsize dst_idx = ~idx; if (priv->s390_options.n_alloc < priv->s390_options.len + 1) { priv->s390_options.n_alloc = NM_MAX(4, (priv->s390_options.len + 1) * 2); priv->s390_options.arr = g_realloc(priv->s390_options.arr, priv->s390_options.n_alloc * sizeof(NMUtilsNamedValue)); } if (dst_idx < priv->s390_options.len) { memmove(&priv->s390_options.arr[dst_idx + 1], &priv->s390_options.arr[dst_idx], (priv->s390_options.len - dst_idx) * sizeof(NMUtilsNamedValue)); } priv->s390_options.arr[dst_idx] = (NMUtilsNamedValue){ .name = g_strdup(key), .value_str = g_strdup(value), }; priv->s390_options.len++; } else { v = &priv->s390_options.arr[idx]; if (nm_streq(value, v->value_str)) return TRUE; g_free((char *) v->value_str); v->value_str = g_strdup(value); } _notify(setting, PROP_S390_OPTIONS); return TRUE; } /** * nm_setting_wired_remove_s390_option: * @setting: the #NMSettingWired * @key: key name for the option to remove * * Remove the s390-specific option referenced by @key from the internal option * list. * * Returns: %TRUE if the option was found and removed from the internal option * list, %FALSE if it was not. **/ gboolean nm_setting_wired_remove_s390_option(NMSettingWired *setting, const char *key) { NMSettingWiredPrivate *priv; gsize dst_idx; gssize idx; g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), FALSE); g_return_val_if_fail(key, FALSE); priv = NM_SETTING_WIRED_GET_PRIVATE(setting); idx = nm_utils_named_value_list_find(priv->s390_options.arr, priv->s390_options.len, key, TRUE); if (idx < 0) return FALSE; dst_idx = idx; g_free((char *) priv->s390_options.arr[dst_idx].name); g_free((char *) priv->s390_options.arr[dst_idx].value_str); if (dst_idx + 1 != priv->s390_options.len) { memmove(&priv->s390_options.arr[dst_idx], &priv->s390_options.arr[dst_idx + 1], (priv->s390_options.len - dst_idx - 1) * sizeof(NMUtilsNamedValue)); } priv->s390_options.len--; _notify(setting, PROP_S390_OPTIONS); return TRUE; } static void _s390_options_clear(NMSettingWiredPrivate *priv) { guint i; for (i = 0; i < priv->s390_options.len; i++) { g_free((char *) priv->s390_options.arr[i].name); g_free((char *) priv->s390_options.arr[i].value_str); } nm_clear_g_free(&priv->s390_options.arr); priv->s390_options.len = 0; priv->s390_options.n_alloc = 0; } void _nm_setting_wired_clear_s390_options(NMSettingWired *setting) { g_return_if_fail(NM_IS_SETTING_WIRED(setting)); _s390_options_clear(NM_SETTING_WIRED_GET_PRIVATE(setting)); } /** * nm_setting_wired_get_valid_s390_options: * @setting: (allow-none): the #NMSettingWired. This argument is unused * and you may pass %NULL. * * Returns a list of valid s390 options. * * The @setting argument is unused and %NULL may be passed instead. * * Returns: (transfer none): a %NULL-terminated array of strings of valid s390 options. **/ const char ** nm_setting_wired_get_valid_s390_options(NMSettingWired *setting) { return valid_s390_opts; } /** * nm_setting_wired_get_wake_on_lan: * @setting: the #NMSettingWired * * Returns the Wake-on-LAN options enabled for the connection * * Returns: the Wake-on-LAN options * * Since: 1.2 */ NMSettingWiredWakeOnLan nm_setting_wired_get_wake_on_lan(NMSettingWired *setting) { g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NM_SETTING_WIRED_WAKE_ON_LAN_NONE); return NM_SETTING_WIRED_GET_PRIVATE(setting)->wol; } /** * nm_setting_wired_get_wake_on_lan_password: * @setting: the #NMSettingWired * * Returns the Wake-on-LAN password. This only applies to * %NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC. * * Returns: the Wake-on-LAN setting password, or %NULL if there is no password. * * Since: 1.2 */ const char * nm_setting_wired_get_wake_on_lan_password(NMSettingWired *setting) { g_return_val_if_fail(NM_IS_SETTING_WIRED(setting), NULL); return NM_SETTING_WIRED_GET_PRIVATE(setting)->wol_password; } static gboolean verify(NMSetting *setting, NMConnection *connection, GError **error) { NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE(setting); GError * local = NULL; guint i; if (!NM_IN_STRSET(priv->port, NULL, "tp", "aui", "bnc", "mii")) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' is not a valid Ethernet port value"), priv->port); g_prefix_error(error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_PORT); return FALSE; } if (!NM_IN_STRSET(priv->duplex, NULL, "half", "full")) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' is not a valid duplex value"), priv->duplex); g_prefix_error(error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_DUPLEX); return FALSE; } if (priv->device_mac_address && !nm_utils_hwaddr_valid(priv->device_mac_address, ETH_ALEN)) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' is not a valid MAC address"), priv->device_mac_address); g_prefix_error(error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS); return FALSE; } for (i = 0; i < priv->mac_address_blacklist->len; i++) { const char *mac = g_array_index(priv->mac_address_blacklist, const char *, i); if (!nm_utils_hwaddr_valid(mac, ETH_ALEN)) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' is not a valid MAC address"), mac); g_prefix_error(error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST); return FALSE; } } if (priv->s390_subchannels) { guint len = g_strv_length(priv->s390_subchannels); if (len != 2 && len != 3) { g_set_error_literal(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("property is invalid")); g_prefix_error(error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_S390_SUBCHANNELS); return FALSE; } } if (!NM_IN_STRSET(priv->s390_nettype, NULL, "qeth", "lcs", "ctc")) { g_set_error_literal(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("property is invalid")); g_prefix_error(error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_S390_NETTYPE); return FALSE; } for (i = 0; i < priv->s390_options.len; i++) { const NMUtilsNamedValue *v = &priv->s390_options.arr[i]; nm_assert(v->name); if (!valid_s390_opts_check(v->name) || v->value_str[0] == '\0' || strlen(v->value_str) > 200) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("invalid '%s' or its value '%s'"), v->name, v->value_str); g_prefix_error(error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_S390_OPTIONS); return FALSE; } } if (priv->cloned_mac_address && !NM_CLONED_MAC_IS_SPECIAL(priv->cloned_mac_address) && !nm_utils_hwaddr_valid(priv->cloned_mac_address, ETH_ALEN)) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' is not a valid MAC address"), priv->cloned_mac_address); g_prefix_error(error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_CLONED_MAC_ADDRESS); return FALSE; } /* generate-mac-address-mask only makes sense with cloned-mac-address "random" or * "stable". Still, let's not be so strict about that and accept the value * even if it is unused. */ if (!_nm_utils_generate_mac_address_mask_parse(priv->generate_mac_address_mask, NULL, NULL, NULL, &local)) { g_set_error_literal(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, local->message); g_prefix_error(error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK); g_error_free(local); return FALSE; } if (NM_FLAGS_ANY(priv->wol, NM_SETTING_WIRED_WAKE_ON_LAN_EXCLUSIVE_FLAGS) && !nm_utils_is_power_of_two(priv->wol)) { g_set_error_literal(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("Wake-on-LAN mode 'default' and 'ignore' are exclusive flags")); g_prefix_error(error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_WAKE_ON_LAN); return FALSE; } if (priv->wol_password && !NM_FLAGS_HAS(priv->wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) { g_set_error_literal(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("Wake-on-LAN password can only be used with magic packet mode")); g_prefix_error(error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD); return FALSE; } if (priv->wol_password && !nm_utils_hwaddr_valid(priv->wol_password, ETH_ALEN)) { g_set_error(error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' is not a valid MAC address"), priv->wol_password); g_prefix_error(error, "%s.%s: ", NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD); return FALSE; } /* Normalizable properties - just return NM_SETTING_VERIFY_NORMALIZABLE for compatibility * with legacy nm-connection-editor which used to save "full" duplex connection as default */ if (((priv->speed) && (!priv->duplex)) || ((!priv->speed) && (priv->duplex))) { g_set_error_literal( error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, priv->auto_negotiate ? _("both speed and duplex should have a valid value or both should be unset") : _("both speed and duplex are required for static link configuration")); return NM_SETTING_VERIFY_NORMALIZABLE; } return TRUE; } static NMTernary compare_property(const NMSettInfoSetting *sett_info, guint property_idx, NMConnection * con_a, NMSetting * set_a, NMConnection * con_b, NMSetting * set_b, NMSettingCompareFlags flags) { if (nm_streq(sett_info->property_infos[property_idx].name, NM_SETTING_WIRED_CLONED_MAC_ADDRESS)) { return !set_b || nm_streq0(NM_SETTING_WIRED_GET_PRIVATE(set_a)->cloned_mac_address, NM_SETTING_WIRED_GET_PRIVATE(set_b)->cloned_mac_address); } return NM_SETTING_CLASS(nm_setting_wired_parent_class) ->compare_property(sett_info, property_idx, con_a, set_a, con_b, set_b, flags); } static GVariant * _override_autoneg_get(const NMSettInfoSetting * sett_info, guint property_idx, NMConnection * connection, NMSetting * setting, NMConnectionSerializationFlags flags, const NMConnectionSerializationOptions *options) { return g_variant_new_boolean(nm_setting_wired_get_auto_negotiate((NMSettingWired *) setting)); } /*****************************************************************************/ static void clear_blacklist_item(char **item_p) { g_free(*item_p); } /*****************************************************************************/ static void get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMSettingWired * setting = NM_SETTING_WIRED(object); NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE(setting); GHashTable * hash; guint i; switch (prop_id) { case PROP_PORT: g_value_set_string(value, nm_setting_wired_get_port(setting)); break; case PROP_SPEED: g_value_set_uint(value, nm_setting_wired_get_speed(setting)); break; case PROP_DUPLEX: g_value_set_string(value, nm_setting_wired_get_duplex(setting)); break; case PROP_AUTO_NEGOTIATE: g_value_set_boolean(value, nm_setting_wired_get_auto_negotiate(setting)); break; case PROP_MAC_ADDRESS: g_value_set_string(value, nm_setting_wired_get_mac_address(setting)); break; case PROP_CLONED_MAC_ADDRESS: g_value_set_string(value, nm_setting_wired_get_cloned_mac_address(setting)); break; case PROP_GENERATE_MAC_ADDRESS_MASK: g_value_set_string(value, nm_setting_wired_get_generate_mac_address_mask(setting)); break; case PROP_MAC_ADDRESS_BLACKLIST: g_value_set_boxed(value, (char **) priv->mac_address_blacklist->data); break; case PROP_MTU: g_value_set_uint(value, nm_setting_wired_get_mtu(setting)); break; case PROP_S390_SUBCHANNELS: g_value_set_boxed(value, priv->s390_subchannels); break; case PROP_S390_NETTYPE: g_value_set_string(value, nm_setting_wired_get_s390_nettype(setting)); break; case PROP_S390_OPTIONS: hash = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free); for (i = 0; i < priv->s390_options.len; i++) { g_hash_table_insert(hash, g_strdup(priv->s390_options.arr[i].name), g_strdup(priv->s390_options.arr[i].value_str)); } g_value_take_boxed(value, hash); break; case PROP_WAKE_ON_LAN: g_value_set_uint(value, priv->wol); break; case PROP_WAKE_ON_LAN_PASSWORD: g_value_set_string(value, priv->wol_password); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE(object); const char *const * blacklist; const char * mac; switch (prop_id) { case PROP_PORT: g_free(priv->port); priv->port = g_value_dup_string(value); break; case PROP_SPEED: priv->speed = g_value_get_uint(value); break; case PROP_DUPLEX: g_free(priv->duplex); priv->duplex = g_value_dup_string(value); break; case PROP_AUTO_NEGOTIATE: priv->auto_negotiate = g_value_get_boolean(value); break; case PROP_MAC_ADDRESS: g_free(priv->device_mac_address); priv->device_mac_address = _nm_utils_hwaddr_canonical_or_invalid(g_value_get_string(value), ETH_ALEN); break; case PROP_CLONED_MAC_ADDRESS: g_free(priv->cloned_mac_address); priv->cloned_mac_address = _nm_utils_hwaddr_canonical_or_invalid(g_value_get_string(value), ETH_ALEN); break; case PROP_GENERATE_MAC_ADDRESS_MASK: g_free(priv->generate_mac_address_mask); priv->generate_mac_address_mask = g_value_dup_string(value); break; case PROP_MAC_ADDRESS_BLACKLIST: blacklist = g_value_get_boxed(value); g_array_set_size(priv->mac_address_blacklist, 0); if (blacklist && *blacklist) { guint i; for (i = 0; blacklist[i]; i++) { mac = _nm_utils_hwaddr_canonical_or_invalid(blacklist[i], ETH_ALEN); g_array_append_val(priv->mac_address_blacklist, mac); } } break; case PROP_MTU: priv->mtu = g_value_get_uint(value); break; case PROP_S390_SUBCHANNELS: if (priv->s390_subchannels) g_strfreev(priv->s390_subchannels); priv->s390_subchannels = g_value_dup_boxed(value); break; case PROP_S390_NETTYPE: g_free(priv->s390_nettype); priv->s390_nettype = g_value_dup_string(value); break; case PROP_S390_OPTIONS: { GHashTable *hash; _s390_options_clear(priv); hash = g_value_get_boxed(value); priv->s390_options.n_alloc = hash ? g_hash_table_size(hash) : 0u; if (priv->s390_options.n_alloc > 0) { gboolean invalid_content = FALSE; GHashTableIter iter; const char * key; const char * val; guint i, j; priv->s390_options.arr = g_new(NMUtilsNamedValue, priv->s390_options.n_alloc); g_hash_table_iter_init(&iter, hash); while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &val)) { if (!key || !val) { invalid_content = TRUE; continue; } nm_assert(priv->s390_options.len < priv->s390_options.n_alloc); priv->s390_options.arr[priv->s390_options.len] = (NMUtilsNamedValue){ .name = g_strdup(key), .value_str = g_strdup(val), }; priv->s390_options.len++; } if (priv->s390_options.len > 1) { nm_utils_named_value_list_sort(priv->s390_options.arr, priv->s390_options.len, NULL, NULL); /* prune duplicate keys. This is only possible if @hash does not use * g_str_equal() as compare function (which would be a bug). * Still, handle this, because we use later binary sort and rely * on unique names. One bug here, should not bork the remainder * of the program. */ j = 1; for (i = 1; i < priv->s390_options.len; i++) { if (nm_streq(priv->s390_options.arr[j - 1].name, priv->s390_options.arr[i].name)) { g_free((char *) priv->s390_options.arr[i].name); g_free((char *) priv->s390_options.arr[i].value_str); invalid_content = TRUE; continue; } priv->s390_options.arr[j++] = priv->s390_options.arr[i]; } priv->s390_options.len = j; } g_return_if_fail(!invalid_content); } } break; case PROP_WAKE_ON_LAN: priv->wol = g_value_get_uint(value); break; case PROP_WAKE_ON_LAN_PASSWORD: g_free(priv->wol_password); priv->wol_password = g_value_dup_string(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } /*****************************************************************************/ static void nm_setting_wired_init(NMSettingWired *setting) { NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE(setting); /* We use GArray rather than GPtrArray so it will automatically be NULL-terminated */ priv->mac_address_blacklist = g_array_new(TRUE, FALSE, sizeof(char *)); g_array_set_clear_func(priv->mac_address_blacklist, (GDestroyNotify) clear_blacklist_item); priv->wol = NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT; } /** * nm_setting_wired_new: * * Creates a new #NMSettingWired object with default values. * * Returns: (transfer full): the new empty #NMSettingWired object **/ NMSetting * nm_setting_wired_new(void) { return g_object_new(NM_TYPE_SETTING_WIRED, NULL); } static void finalize(GObject *object) { NMSettingWiredPrivate *priv = NM_SETTING_WIRED_GET_PRIVATE(object); g_free(priv->port); g_free(priv->duplex); g_free(priv->s390_nettype); _s390_options_clear(priv); g_free(priv->device_mac_address); g_free(priv->cloned_mac_address); g_free(priv->generate_mac_address_mask); g_array_unref(priv->mac_address_blacklist); if (priv->s390_subchannels) g_strfreev(priv->s390_subchannels); g_free(priv->wol_password); G_OBJECT_CLASS(nm_setting_wired_parent_class)->finalize(object); } static void nm_setting_wired_class_init(NMSettingWiredClass *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(); g_type_class_add_private(klass, sizeof(NMSettingWiredPrivate)); object_class->get_property = get_property; object_class->set_property = set_property; object_class->finalize = finalize; setting_class->verify = verify; setting_class->compare_property = compare_property; /** * NMSettingWired:port: * * Specific port type to use if the device supports multiple * attachment methods. One of "tp" (Twisted Pair), "aui" (Attachment Unit * Interface), "bnc" (Thin Ethernet) or "mii" (Media Independent Interface). * If the device supports only one port type, this setting is ignored. **/ /* ---ifcfg-rh--- * property: port * variable: (none) * description: The property is not saved by the plugin. * ---end--- */ obj_properties[PROP_PORT] = g_param_spec_string(NM_SETTING_WIRED_PORT, "", "", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * NMSettingWired:speed: * * When a value greater than 0 is set, configures the device to use * the specified speed. If "auto-negotiate" is "yes" the specified * speed will be the only one advertised during link negotiation: * this works only for BASE-T 802.3 specifications and is useful for * enforcing gigabit speeds, as in this case link negotiation is * mandatory. * If the value is unset (0, the default), the link configuration will be * either skipped (if "auto-negotiate" is "no", the default) or will * be auto-negotiated (if "auto-negotiate" is "yes") and the local device * will advertise all the supported speeds. * In Mbit/s, ie 100 == 100Mbit/s. * Must be set together with the "duplex" property when non-zero. * Before specifying a speed value be sure your device supports it. **/ /* ---ifcfg-rh--- * property: speed * variable: ETHTOOL_OPTS * description: Fixed speed for the ethernet link. It is added as "speed" * parameter in the ETHTOOL_OPTS variable. * ---end--- */ obj_properties[PROP_SPEED] = g_param_spec_uint(NM_SETTING_WIRED_SPEED, "", "", 0, G_MAXUINT32, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * NMSettingWired:duplex: * * When a value is set, either "half" or "full", configures the device * to use the specified duplex mode. If "auto-negotiate" is "yes" the * specified duplex mode will be the only one advertised during link * negotiation: this works only for BASE-T 802.3 specifications and is * useful for enforcing gigabits modes, as in these cases link negotiation * is mandatory. * If the value is unset (the default), the link configuration will be * either skipped (if "auto-negotiate" is "no", the default) or will * be auto-negotiated (if "auto-negotiate" is "yes") and the local device * will advertise all the supported duplex modes. * Must be set together with the "speed" property if specified. * Before specifying a duplex mode be sure your device supports it. **/ /* ---ifcfg-rh--- * property: duplex * variable: ETHTOOL_OPTS * description: Fixed duplex mode for the ethernet link. It is added as * "duplex" parameter in the ETHOOL_OPTS variable. * ---end--- */ obj_properties[PROP_DUPLEX] = g_param_spec_string(NM_SETTING_WIRED_DUPLEX, "", "", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * NMSettingWired:auto-negotiate: * * When %TRUE, enforce auto-negotiation of speed and duplex mode. * If "speed" and "duplex" properties are both specified, only that * single mode will be advertised and accepted during the link * auto-negotiation process: this works only for BASE-T 802.3 specifications * and is useful for enforcing gigabits modes, as in these cases link * negotiation is mandatory. * When %FALSE, "speed" and "duplex" properties should be both set or * link configuration will be skipped. **/ /* ---ifcfg-rh--- * property: auto-negotiate * variable: ETHTOOL_OPTS * description: Whether link speed and duplex autonegotiation is enabled. * It is not saved only if disabled and no values are provided for the * "speed" and "duplex" parameters (skips link configuration). * ---end--- */ obj_properties[PROP_AUTO_NEGOTIATE] = g_param_spec_boolean(NM_SETTING_WIRED_AUTO_NEGOTIATE, "", "", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); _nm_properties_override_gobj(properties_override, obj_properties[PROP_AUTO_NEGOTIATE], NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_BOOLEAN, .to_dbus_fcn = _override_autoneg_get, )); /** * NMSettingWired:mac-address: * * If specified, this connection will only apply to the Ethernet device * whose permanent MAC address matches. This property does not change the * MAC address of the device (i.e. MAC spoofing). **/ /* ---keyfile--- * property: mac-address * format: usual hex-digits-and-colons notation * description: MAC address in traditional hex-digits-and-colons notation * (e.g. 00:22:68:12:79:A2), or semicolon separated list of 6 bytes (obsolete) * (e.g. 0;34;104;18;121;162) * ---end--- * ---ifcfg-rh--- * property: mac-address * variable: HWADDR * description: Hardware address of the device in traditional hex-digits-and-colons * notation (e.g. 00:22:68:14:5A:05). * Note that for initscripts this is the current MAC address of the device as found * during ifup. For NetworkManager this is the permanent MAC address. Or in case no * permanent MAC address exists, the MAC address initially configured on the device. * ---end--- */ obj_properties[PROP_MAC_ADDRESS] = g_param_spec_string( NM_SETTING_WIRED_MAC_ADDRESS, "", "", NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); _nm_properties_override_gobj(properties_override, obj_properties[PROP_MAC_ADDRESS], &nm_sett_info_propert_type_mac_address); /** * NMSettingWired:cloned-mac-address: * * If specified, request that the device use this MAC address instead. * This is known as MAC cloning or spoofing. * * Beside explicitly specifying a MAC address, the special values "preserve", "permanent", * "random" and "stable" are supported. * "preserve" means not to touch the MAC address on activation. * "permanent" means to use the permanent hardware address if the device * has one (otherwise this is treated as "preserve"). * "random" creates a random MAC address on each connect. * "stable" creates a hashed MAC address based on connection.stable-id and a * machine dependent key. * * If unspecified, the value can be overwritten via global defaults, see manual * of NetworkManager.conf. If still unspecified, it defaults to "preserve" * (older versions of NetworkManager may use a different default value). * * On D-Bus, this field is expressed as "assigned-mac-address" or the deprecated * "cloned-mac-address". **/ /* ---keyfile--- * property: cloned-mac-address * format: usual hex-digits-and-colons notation * description: Cloned MAC address in traditional hex-digits-and-colons notation * (e.g. 00:22:68:12:79:B2), or semicolon separated list of 6 bytes (obsolete) * (e.g. 0;34;104;18;121;178). * ---end--- * ---ifcfg-rh--- * property: cloned-mac-address * variable: MACADDR * description: Cloned (spoofed) MAC address in traditional hex-digits-and-colons * notation (e.g. 00:22:68:14:5A:99). * ---end--- * ---dbus--- * property: cloned-mac-address * format: byte array * description: This D-Bus field is deprecated in favor of "assigned-mac-address" * which is more flexible and allows specifying special variants like "random". * For libnm and nmcli, this field is called "cloned-mac-address". * ---end--- */ obj_properties[PROP_CLONED_MAC_ADDRESS] = g_param_spec_string( NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "", "", NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); _nm_properties_override_gobj(properties_override, obj_properties[PROP_CLONED_MAC_ADDRESS], &nm_sett_info_propert_type_cloned_mac_address); /* ---dbus--- * property: assigned-mac-address * format: string * description: The new field for the cloned MAC address. It can be either * a hardware address in ASCII representation, or one of the special values * "preserve", "permanent", "random" or "stable". * This field replaces the deprecated "cloned-mac-address" on D-Bus, which * can only contain explicit hardware addresses. Note that this property * only exists in D-Bus API. libnm and nmcli continue to call this property * "cloned-mac-address". * ---end--- */ _nm_properties_override_dbus(properties_override, "assigned-mac-address", &nm_sett_info_propert_type_assigned_mac_address); /** * NMSettingWired:generate-mac-address-mask: * * With #NMSettingWired:cloned-mac-address setting "random" or "stable", * by default all bits of the MAC address are scrambled and a locally-administered, * unicast MAC address is created. This property allows to specify that certain bits * are fixed. Note that the least significant bit of the first MAC address will * always be unset to create a unicast MAC address. * * If the property is %NULL, it is eligible to be overwritten by a default * connection setting. If the value is still %NULL or an empty string, the * default is to create a locally-administered, unicast MAC address. * * If the value contains one MAC address, this address is used as mask. The set * bits of the mask are to be filled with the current MAC address of the device, * while the unset bits are subject to randomization. * Setting "FE:FF:FF:00:00:00" means to preserve the OUI of the current MAC address * and only randomize the lower 3 bytes using the "random" or "stable" algorithm. * * If the value contains one additional MAC address after the mask, * this address is used instead of the current MAC address to fill the bits * that shall not be randomized. For example, a value of * "FE:FF:FF:00:00:00 68:F7:28:00:00:00" will set the OUI of the MAC address * to 68:F7:28, while the lower bits are randomized. A value of * "02:00:00:00:00:00 00:00:00:00:00:00" will create a fully scrambled * globally-administered, burned-in MAC address. * * If the value contains more than one additional MAC addresses, one of * them is chosen randomly. For example, "02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00" * will create a fully scrambled MAC address, randomly locally or globally * administered. **/ /* ---ifcfg-rh--- * property: generate-mac-address-mask * variable: GENERATE_MAC_ADDRESS_MASK(+) * description: the MAC address mask for generating randomized and stable * cloned-mac-address. * ---end--- */ obj_properties[PROP_GENERATE_MAC_ADDRESS_MASK] = g_param_spec_string( NM_SETTING_WIRED_GENERATE_MAC_ADDRESS_MASK, "", "", NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); /** * NMSettingWired:mac-address-blacklist: * * If specified, this connection will never apply to the Ethernet device * whose permanent MAC address matches an address in the list. Each MAC * address is in the standard hex-digits-and-colons notation * (00:11:22:33:44:55). **/ /* ---keyfile--- * property: mac-address-blacklist * format: list of MACs (separated with semicolons) * description: MAC address blacklist. * example: mac-address-blacklist= 00:22:68:12:79:A6;00:22:68:12:79:78 * ---end--- * ---ifcfg-rh--- * property: mac-address-blacklist * variable: HWADDR_BLACKLIST(+) * description: It denies usage of the connection for any device whose address * is listed. * example: HWADDR_BLACKLIST="00:22:68:11:69:08 00:11:22:11:44:55" * ---end--- */ obj_properties[PROP_MAC_ADDRESS_BLACKLIST] = g_param_spec_boxed( NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, "", "", G_TYPE_STRV, G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); /** * NMSettingWired:mtu: * * If non-zero, only transmit packets of the specified size or smaller, * breaking larger packets up into multiple Ethernet frames. **/ /* ---ifcfg-rh--- * property: mtu * variable: MTU * description: MTU of the interface. * ---end--- */ obj_properties[PROP_MTU] = g_param_spec_uint(NM_SETTING_WIRED_MTU, "", "", 0, G_MAXUINT32, 0, G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS); /** * NMSettingWired:s390-subchannels: * * Identifies specific subchannels that this network device uses for * communication with z/VM or s390 host. Like the * #NMSettingWired:mac-address property for non-z/VM devices, this property * can be used to ensure this connection only applies to the network device * that uses these subchannels. The list should contain exactly 3 strings, * and each string may only be composed of hexadecimal characters and the * period (.) character. **/ /* ---ifcfg-rh--- * property: s390-subchannels * variable: SUBCHANNELS * description: Subchannels for IBM S390 hosts. * example: SUBCHANNELS=0.0.b00a,0.0.b00b,0.0.b00c * ---end--- */ obj_properties[PROP_S390_SUBCHANNELS] = g_param_spec_boxed( NM_SETTING_WIRED_S390_SUBCHANNELS, "", "", G_TYPE_STRV, G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); /** * NMSettingWired:s390-nettype: * * s390 network device type; one of "qeth", "lcs", or "ctc", representing * the different types of virtual network devices available on s390 systems. **/ /* ---ifcfg-rh--- * property: s390-nettype * variable: NETTYPE * values: "qeth", "lcs" or "ctc" * description: Network type of the S390 host. * example: NETTYPE=qeth * ---end--- */ obj_properties[PROP_S390_NETTYPE] = g_param_spec_string( NM_SETTING_WIRED_S390_NETTYPE, "", "", NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); /** * NMSettingWired:s390-options: (type GHashTable(utf8,utf8)): * * Dictionary of key/value pairs of s390-specific device options. Both keys * and values must be strings. Allowed keys include "portno", "layer2", * "portname", "protocol", among others. Key names must contain only * alphanumeric characters (ie, [a-zA-Z0-9]). **/ /* ---ifcfg-rh--- * property: s390-options * variable: OPTIONS and PORTNAME, CTCPROTO, * description: S390 device options. All options go to OPTIONS, except for * "portname" and "ctcprot" that have their own variables. * ---end--- */ obj_properties[PROP_S390_OPTIONS] = g_param_spec_boxed( NM_SETTING_WIRED_S390_OPTIONS, "", "", G_TYPE_HASH_TABLE, G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); _nm_properties_override_gobj(properties_override, obj_properties[PROP_S390_OPTIONS], &nm_sett_info_propert_type_strdict); /** * NMSettingWired:wake-on-lan: * * The #NMSettingWiredWakeOnLan options to enable. Not all devices support all options. * May be any combination of %NM_SETTING_WIRED_WAKE_ON_LAN_PHY, * %NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST, %NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST, * %NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST, %NM_SETTING_WIRED_WAKE_ON_LAN_ARP, * %NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC or the special values * %NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT (to use global settings) and * %NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE (to disable management of Wake-on-LAN in * NetworkManager). * * Since: 1.2 **/ obj_properties[PROP_WAKE_ON_LAN] = g_param_spec_uint(NM_SETTING_WIRED_WAKE_ON_LAN, "", "", 0, G_MAXUINT32, NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * NMSettingWired:wake-on-lan-password: * * If specified, the password used with magic-packet-based * Wake-on-LAN, represented as an Ethernet MAC address. If %NULL, * no password will be required. * * Since: 1.2 **/ obj_properties[PROP_WAKE_ON_LAN_PASSWORD] = g_param_spec_string(NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, "", "", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); _nm_setting_class_commit_full(setting_class, NM_META_SETTING_TYPE_WIRED, NULL, properties_override); }