/** * nm_setting_bond_get_option_default: * @setting: the #NMSettingBond * @name: the name of the option * * Returns: the value of the bond option if not overridden by an entry in * the #NMSettingBond:options property. **/ const char * nm_setting_bond_get_option_default (NMSettingBond *setting, const char *name) { const char *mode; guint i; g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NULL); g_return_val_if_fail (nm_setting_bond_validate_option (name, NULL), NULL); if (nm_streq (name, NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM)) { /* The default value depends on the current mode */ mode = nm_setting_bond_get_option_by_name (setting, NM_SETTING_BOND_OPTION_MODE); if ( nm_streq0 (mode, "4") || nm_streq0 (mode, "802.3ad")) return "00:00:00:00:00:00"; else return ""; } for (i = 0; i < G_N_ELEMENTS (defaults); i++) { if (g_strcmp0 (defaults[i].opt, name) == 0) return defaults[i].val; } /* Any option that passes nm_setting_bond_validate_option() should also be found in defaults */ g_assert_not_reached (); }
/** * nm_setting_bond_add_option: * @setting: the #NMSettingBond * @name: 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. Option names may contain only alphanumeric characters * (ie [a-zA-Z0-9]). Adding a new name replaces any existing name/value pair * that may already exist. * * The order of how to set several options is relevant because there are options * that conflict with each other. * * Returns: %TRUE if the option was valid and was added to the internal option * list, %FALSE if it was not. **/ gboolean nm_setting_bond_add_option (NMSettingBond *setting, const char *name, const char *value) { NMSettingBondPrivate *priv; g_return_val_if_fail (NM_IS_SETTING_BOND (setting), FALSE); if (!value || !nm_setting_bond_validate_option (name, value)) return FALSE; priv = NM_SETTING_BOND_GET_PRIVATE (setting); g_hash_table_insert (priv->options, g_strdup (name), g_strdup (value)); if ( !strcmp (name, NM_SETTING_BOND_OPTION_MIIMON) && strcmp (value, "0") != 0) { g_hash_table_remove (priv->options, NM_SETTING_BOND_OPTION_ARP_INTERVAL); g_hash_table_remove (priv->options, NM_SETTING_BOND_OPTION_ARP_IP_TARGET); } else if ( !strcmp (name, NM_SETTING_BOND_OPTION_ARP_INTERVAL) && strcmp (value, "0") != 0) { g_hash_table_remove (priv->options, NM_SETTING_BOND_OPTION_MIIMON); g_hash_table_remove (priv->options, NM_SETTING_BOND_OPTION_DOWNDELAY); g_hash_table_remove (priv->options, NM_SETTING_BOND_OPTION_UPDELAY); } g_object_notify (G_OBJECT (setting), NM_SETTING_BOND_OPTIONS); return TRUE; }
/** * nm_setting_bond_get_option: * @setting: the #NMSettingBond * @idx: index of the desired option, from 0 to * nm_setting_bond_get_num_options() - 1 * @out_name: (out) (transfer none): on return, the name of the bonding option; * this value is owned by the setting and should not be modified * @out_value: (out) (transfer none): on return, the value of the name of the * bonding option; this value is owned by the setting and should not be * modified * * Given an index, return the value of the bonding option at that index. Indexes * are *not* guaranteed to be static across modifications to options done by * nm_setting_bond_add_option() and nm_setting_bond_remove_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_bond_get_option (NMSettingBond *setting, guint32 idx, const char **out_name, const char **out_value) { NMSettingBondPrivate *priv; GList *keys; const char *_key = NULL, *_value = NULL; g_return_val_if_fail (NM_IS_SETTING_BOND (setting), FALSE); priv = NM_SETTING_BOND_GET_PRIVATE (setting); if (idx >= nm_setting_bond_get_num_options (setting)) return FALSE; keys = g_hash_table_get_keys (priv->options); _key = g_list_nth_data (keys, idx); _value = g_hash_table_lookup (priv->options, _key); if (out_name) *out_name = _key; if (out_value) *out_value = _value; g_list_free (keys); return TRUE; }
/** * nm_setting_bond_get_num_options: * @setting: the #NMSettingBond * * Returns the number of options that should be set for this bond when it * is activated. This can be used to retrieve each option individually * using nm_setting_bond_get_option(). * * Returns: the number of bonding options **/ guint32 nm_setting_bond_get_num_options (NMSettingBond *setting) { g_return_val_if_fail (NM_IS_SETTING_BOND (setting), 0); return g_hash_table_size (NM_SETTING_BOND_GET_PRIVATE (setting)->options); }
/** * nm_setting_bond_get_interface_name: * @setting: the #NMSettingBond * * Returns: the #NMSettingBond:interface-name property of the setting **/ const char * nm_setting_bond_get_interface_name (NMSettingBond *setting) { g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NULL); return NM_SETTING_BOND_GET_PRIVATE (setting)->interface_name; }
static void read_hash_of_string (GKeyFile *file, NMSetting *setting, const char *key) { char **keys, **iter; char *value; const char *setting_name = nm_setting_get_name (setting); keys = nm_keyfile_plugin_kf_get_keys (file, setting_name, NULL, NULL); if (!keys || !*keys) return; for (iter = keys; *iter; iter++) { value = nm_keyfile_plugin_kf_get_string (file, setting_name, *iter, NULL); if (!value) continue; if (NM_IS_SETTING_VPN (setting)) { if (strcmp (*iter, NM_SETTING_VPN_SERVICE_TYPE)) nm_setting_vpn_add_data_item (NM_SETTING_VPN (setting), *iter, value); } if (NM_IS_SETTING_BOND (setting)) { if (strcmp (*iter, NM_SETTING_BOND_INTERFACE_NAME)) nm_setting_bond_add_option (NM_SETTING_BOND (setting), *iter, value); } g_free (value); } g_strfreev (keys); }
/** * nm_setting_bond_get_option_by_name: * @setting: the #NMSettingBond * @name: the option name for which to retrieve the value * * Returns the value associated with the bonding option specified by * @name, 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_bond_get_option_by_name (NMSettingBond *setting, const char *name) { g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NULL); if (!nm_setting_bond_validate_option (name, NULL)) return NULL; return g_hash_table_lookup (NM_SETTING_BOND_GET_PRIVATE (setting)->options, name); }
/** * nm_setting_bond_get_option_type: * @setting: the #NMSettingBond * @name: the name of the option * * Returns: the type of the bond option. **/ NMBondOptionType _nm_setting_bond_get_option_type (NMSettingBond *setting, const char *name) { guint i; g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NM_BOND_OPTION_TYPE_INT); g_return_val_if_fail (nm_setting_bond_validate_option (name, NULL), NM_BOND_OPTION_TYPE_INT); for (i = 0; i < G_N_ELEMENTS (defaults); i++) { if (nm_streq0 (defaults[i].opt, name)) return defaults[i].opt_type; } /* Any option that passes nm_setting_bond_validate_option() should also be found in defaults */ g_assert_not_reached (); }
/** * nm_setting_bond_get_option_default: * @setting: the #NMSettingBond * @name: the name of the option * * Returns: the value of the bond option if not overridden by an entry in * the #NMSettingBond:options property. **/ const char * nm_setting_bond_get_option_default (NMSettingBond *setting, const char *name) { guint i; g_return_val_if_fail (NM_IS_SETTING_BOND (setting), NULL); g_return_val_if_fail (nm_setting_bond_validate_option (name, NULL), NULL); for (i = 0; i < G_N_ELEMENTS (defaults); i++) { if (g_strcmp0 (defaults[i].opt, name) == 0) return defaults[i].val; } /* Any option that passes nm_setting_bond_validate_option() should also be found in defaults */ g_assert_not_reached (); }
/** * nm_setting_bond_remove_option: * @setting: the #NMSettingBond * @name: name of the option to remove * * Remove the bonding option referenced by @name 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_bond_remove_option (NMSettingBond *setting, const char *name) { gboolean found; g_return_val_if_fail (NM_IS_SETTING_BOND (setting), FALSE); if (!nm_setting_bond_validate_option (name, NULL)) return FALSE; found = g_hash_table_remove (NM_SETTING_BOND_GET_PRIVATE (setting)->options, name); if (found) g_object_notify (G_OBJECT (setting), NM_SETTING_BOND_OPTIONS); return found; }
static void read_one_setting_value (NMSetting *setting, const char *key, const GValue *value, GParamFlags flags, gpointer user_data) { ReadInfo *info = user_data; const char *setting_name; GType type; GError *err = NULL; gboolean check_for_key = TRUE; KeyParser *parser = &key_parsers[0]; /* Property is not writable */ if (!(flags & G_PARAM_WRITABLE)) return; /* Setting name gets picked up from the keyfile's section name instead */ if (!strcmp (key, NM_SETTING_NAME)) return; /* Don't read the NMSettingConnection object's 'read-only' property */ if ( NM_IS_SETTING_CONNECTION (setting) && !strcmp (key, NM_SETTING_CONNECTION_READ_ONLY)) return; setting_name = nm_setting_get_name (setting); /* Look through the list of handlers for non-standard format key values */ while (parser->setting_name) { if (!strcmp (parser->setting_name, setting_name) && !strcmp (parser->key, key)) { check_for_key = parser->check_for_key; break; } parser++; } /* VPN properties don't have the exact key name */ if (NM_IS_SETTING_VPN (setting)) check_for_key = FALSE; /* Bonding 'options' don't have the exact key name. The options are right under [bond] group. */ if (NM_IS_SETTING_BOND (setting)) check_for_key = FALSE; /* Check for the exact key in the GKeyFile if required. Most setting * properties map 1:1 to a key in the GKeyFile, but for those properties * like IP addresses and routes where more than one value is actually * encoded by the setting property, this won't be true. */ if (check_for_key && !nm_keyfile_plugin_kf_has_key (info->keyfile, setting_name, key, &err)) { /* Key doesn't exist or an error ocurred, thus nothing to do. */ if (err) { g_warning ("Error loading setting '%s' value: %s", setting_name, err->message); g_error_free (err); } return; } /* If there's a custom parser for this key, handle that before the generic * parsers below. */ if (parser->setting_name) { (*parser->parser) (setting, key, info->keyfile, info->keyfile_path); return; } type = G_VALUE_TYPE (value); if (type == G_TYPE_STRING) { char *str_val; str_val = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, key, NULL); g_object_set (setting, key, str_val, NULL); g_free (str_val); } else if (type == G_TYPE_UINT) { int int_val; int_val = nm_keyfile_plugin_kf_get_integer (info->keyfile, setting_name, key, NULL); if (int_val < 0) g_warning ("Casting negative value (%i) to uint", int_val); g_object_set (setting, key, int_val, NULL); } else if (type == G_TYPE_INT) { int int_val; int_val = nm_keyfile_plugin_kf_get_integer (info->keyfile, setting_name, key, NULL); g_object_set (setting, key, int_val, NULL); } else if (type == G_TYPE_BOOLEAN) { gboolean bool_val; bool_val = nm_keyfile_plugin_kf_get_boolean (info->keyfile, setting_name, key, NULL); g_object_set (setting, key, bool_val, NULL); } else if (type == G_TYPE_CHAR) { int int_val; int_val = nm_keyfile_plugin_kf_get_integer (info->keyfile, setting_name, key, NULL); if (int_val < G_MININT8 || int_val > G_MAXINT8) g_warning ("Casting value (%i) to char", int_val); g_object_set (setting, key, int_val, NULL); } else if (type == G_TYPE_UINT64) { char *tmp_str; guint64 uint_val; tmp_str = nm_keyfile_plugin_kf_get_value (info->keyfile, setting_name, key, NULL); uint_val = g_ascii_strtoull (tmp_str, NULL, 10); g_free (tmp_str); g_object_set (setting, key, uint_val, NULL); } else if (type == DBUS_TYPE_G_UCHAR_ARRAY) { gint *tmp; GByteArray *array; gsize length; int i; tmp = nm_keyfile_plugin_kf_get_integer_list (info->keyfile, setting_name, key, &length, NULL); array = g_byte_array_sized_new (length); for (i = 0; i < length; i++) { int val = tmp[i]; unsigned char v = (unsigned char) (val & 0xFF); if (val < 0 || val > 255) { g_warning ("%s: %s / %s ignoring invalid byte element '%d' (not " " between 0 and 255 inclusive)", __func__, setting_name, key, val); } else g_byte_array_append (array, (const unsigned char *) &v, sizeof (v)); } g_object_set (setting, key, array, NULL); g_byte_array_free (array, TRUE); g_free (tmp); } else if (type == DBUS_TYPE_G_LIST_OF_STRING) { gchar **sa; gsize length; int i; GSList *list = NULL; sa = nm_keyfile_plugin_kf_get_string_list (info->keyfile, setting_name, key, &length, NULL); for (i = 0; i < length; i++) list = g_slist_prepend (list, sa[i]); list = g_slist_reverse (list); g_object_set (setting, key, list, NULL); g_slist_free (list); g_strfreev (sa); } else if (type == DBUS_TYPE_G_MAP_OF_STRING) { read_hash_of_string (info->keyfile, setting, key); } else if (type == DBUS_TYPE_G_UINT_ARRAY) { if (!read_array_of_uint (info->keyfile, setting, key)) { g_warning ("Unhandled setting property type (read): '%s/%s' : '%s'", setting_name, key, G_VALUE_TYPE_NAME (value)); } } else { g_warning ("Unhandled setting property type (read): '%s/%s' : '%s'", setting_name, key, G_VALUE_TYPE_NAME (value)); } }