diff options
| author | Michael Biebl <biebl@debian.org> | 2013-02-03 14:49:22 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2013-02-03 14:49:22 +0100 |
| commit | 9c202e3e860b3be9e1f8882630b69affbb130102 (patch) | |
| tree | 8202bf39f2129486971fa7d5ae0dee61a561aa53 /libnm-util/nm-connection.c | |
| parent | 36cb2f364a821e1be50b23e03a18891ec55adb06 (diff) | |
Imported Upstream version 0.9.7.995 upstream/0.9.7.995
Diffstat (limited to 'libnm-util/nm-connection.c')
| -rw-r--r-- | libnm-util/nm-connection.c | 366 |
1 files changed, 149 insertions, 217 deletions
diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index 66df511f..47a9ec09 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -30,6 +30,7 @@ #include "nm-utils.h" #include "nm-utils-private.h" #include "nm-dbus-glib-types.h" +#include "nm-setting-private.h" #include "nm-setting-8021x.h" #include "nm-setting-bluetooth.h" @@ -48,6 +49,8 @@ #include "nm-setting-vpn.h" #include "nm-setting-olpc-mesh.h" #include "nm-setting-bond.h" +#include "nm-setting-bridge.h" +#include "nm-setting-bridge-port.h" #include "nm-setting-vlan.h" #include "nm-setting-serial.h" #include "nm-setting-gsm.h" @@ -116,203 +119,116 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; +/*************************************************************/ + static GHashTable *registered_settings = NULL; -#define DEFAULT_MAP_SIZE 20 +static void __attribute__((constructor)) +_ensure_registered (void) +{ + g_type_init (); + _nm_utils_register_value_transformations (); + if (G_UNLIKELY (registered_settings == NULL)) + registered_settings = g_hash_table_new (g_str_hash, g_str_equal); +} -static struct SettingInfo { - const char *name; +typedef struct { GType type; guint32 priority; - gboolean base_type; GQuark error_quark; -} default_map[DEFAULT_MAP_SIZE] = { { NULL } }; - -static void -setting_register (const char *name, GType type) -{ - g_return_if_fail (name != NULL); - g_return_if_fail (G_TYPE_IS_INSTANTIATABLE (type)); - - if (G_UNLIKELY (!registered_settings)) { - registered_settings = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_free); - } - - if (g_hash_table_lookup (registered_settings, name)) - g_warning ("Already have a creator function for '%s', overriding", name); - - g_hash_table_insert (registered_settings, g_strdup (name), g_strdup (g_type_name (type))); -} +} SettingInfo; -#if 0 -static void -setting_unregister (const char *name) -{ - if (registered_settings) - g_hash_table_remove (registered_settings, name); -} -#endif - -static void -register_one_setting (const char *name, - GType type, - GQuark error_quark, - guint32 priority, - gboolean base_type) +/* + * _nm_register_setting: + * @name: the name of the #NMSetting object to register + * @type: the #GType of the #NMSetting + * @priority: the sort priority of the setting, see below + * @error_quark: the setting's error quark + * + * INTERNAL ONLY: registers a setting's internal properties, like its priority + * and its error quark type, with libnm-util. + * + * A setting's priority should roughly follow the OSI layer model, but it also + * controls which settings get asked for secrets first. Thus settings which + * relate to things that must be working first, like hardware, should get a + * higher priority than things which layer on top of the hardware. For example, + * the GSM/CDMA settings should provide secrets before the PPP setting does, + * because a PIN is required to unlock the device before PPP can even start. + * Even settings without secrets should be assigned the right priority. + * + * 0: reserved for the Connection setting + * + * 1: hardware-related settings like Ethernet, WiFi, Infiniband, Bridge, etc. + * These priority 1 settings are also "base types", which means that at least + * one of them is required for the connection to be valid, and their name is + * valid in the 'type' property of the Connection setting. + * + * 2: hardware-related auxiliary settings that require a base setting to be + * successful first, like WiFi security, 802.1x, etc. + * + * 3: hardware-independent settings that are required before IP connectivity + * can be established, like PPP, PPPoE, etc. + * + * 4: IP-level stuff + */ +void +_nm_register_setting (const char *name, + const GType type, + const guint32 priority, + const GQuark error_quark) { - static guint32 i = 0; - - g_return_if_fail (i < DEFAULT_MAP_SIZE); - g_return_if_fail (default_map[i].name == NULL); + SettingInfo *info; - default_map[i].name = name; - default_map[i].type = type; - default_map[i].error_quark = error_quark; - default_map[i].priority = priority; - default_map[i].base_type = base_type; - i++; - - setting_register (name, type); -} + g_return_if_fail (name != NULL); + g_return_if_fail (type != G_TYPE_INVALID); + g_return_if_fail (type != G_TYPE_NONE); + g_return_if_fail (error_quark != 0); + g_return_if_fail (priority <= 4); -static void -register_default_settings (void) -{ - _nm_utils_register_value_transformations (); + _ensure_registered (); - if (G_LIKELY (default_map[0].name)) + if (G_LIKELY (g_hash_table_lookup (registered_settings, name))) return; - register_one_setting (NM_SETTING_CONNECTION_SETTING_NAME, - NM_TYPE_SETTING_CONNECTION, - NM_SETTING_CONNECTION_ERROR, - 0, FALSE); - - register_one_setting (NM_SETTING_WIRED_SETTING_NAME, - NM_TYPE_SETTING_WIRED, - NM_SETTING_WIRED_ERROR, - 1, TRUE); - - register_one_setting (NM_SETTING_WIRELESS_SETTING_NAME, - NM_TYPE_SETTING_WIRELESS, - NM_SETTING_WIRELESS_ERROR, - 1, TRUE); - - register_one_setting (NM_SETTING_OLPC_MESH_SETTING_NAME, - NM_TYPE_SETTING_OLPC_MESH, - NM_SETTING_OLPC_MESH_ERROR, - 1, TRUE); - - register_one_setting (NM_SETTING_GSM_SETTING_NAME, - NM_TYPE_SETTING_GSM, - NM_SETTING_GSM_ERROR, - 1, TRUE); - - register_one_setting (NM_SETTING_CDMA_SETTING_NAME, - NM_TYPE_SETTING_CDMA, - NM_SETTING_CDMA_ERROR, - 1, TRUE); - - register_one_setting (NM_SETTING_BLUETOOTH_SETTING_NAME, - NM_TYPE_SETTING_BLUETOOTH, - NM_SETTING_BLUETOOTH_ERROR, - 1, TRUE); - - register_one_setting (NM_SETTING_WIMAX_SETTING_NAME, - NM_TYPE_SETTING_WIMAX, - NM_SETTING_WIMAX_ERROR, - 1, TRUE); - - register_one_setting (NM_SETTING_BOND_SETTING_NAME, - NM_TYPE_SETTING_BOND, - NM_SETTING_BOND_ERROR, - 1, TRUE); - - register_one_setting (NM_SETTING_INFINIBAND_SETTING_NAME, - NM_TYPE_SETTING_INFINIBAND, - NM_SETTING_INFINIBAND_ERROR, - 1, TRUE); - - register_one_setting (NM_SETTING_VLAN_SETTING_NAME, - NM_TYPE_SETTING_VLAN, - NM_SETTING_VLAN_ERROR, - 1, TRUE); - - register_one_setting (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NM_TYPE_SETTING_WIRELESS_SECURITY, - NM_SETTING_WIRELESS_SECURITY_ERROR, - 2, FALSE); - - register_one_setting (NM_SETTING_SERIAL_SETTING_NAME, - NM_TYPE_SETTING_SERIAL, - NM_SETTING_SERIAL_ERROR, - 2, FALSE); - - register_one_setting (NM_SETTING_PPP_SETTING_NAME, - NM_TYPE_SETTING_PPP, - NM_SETTING_PPP_ERROR, - 3, FALSE); - - register_one_setting (NM_SETTING_PPPOE_SETTING_NAME, - NM_TYPE_SETTING_PPPOE, - NM_SETTING_PPPOE_ERROR, - 3, TRUE); - - register_one_setting (NM_SETTING_ADSL_SETTING_NAME, - NM_TYPE_SETTING_ADSL, - NM_SETTING_ADSL_ERROR, - 3, TRUE); - - register_one_setting (NM_SETTING_802_1X_SETTING_NAME, - NM_TYPE_SETTING_802_1X, - NM_SETTING_802_1X_ERROR, - 3, FALSE); - - register_one_setting (NM_SETTING_VPN_SETTING_NAME, - NM_TYPE_SETTING_VPN, - NM_SETTING_VPN_ERROR, - 4, TRUE); - - register_one_setting (NM_SETTING_IP4_CONFIG_SETTING_NAME, - NM_TYPE_SETTING_IP4_CONFIG, - NM_SETTING_IP4_CONFIG_ERROR, - 6, FALSE); - - register_one_setting (NM_SETTING_IP6_CONFIG_SETTING_NAME, - NM_TYPE_SETTING_IP6_CONFIG, - NM_SETTING_IP6_CONFIG_ERROR, - 6, FALSE); - - /* Be sure to update DEFAULT_MAP_SIZE if you add another setting!! */ + if (priority == 0) + g_assert_cmpstr (name, ==, NM_SETTING_CONNECTION_SETTING_NAME); + + info = g_slice_new0 (SettingInfo); + info->type = type; + info->priority = priority; + info->error_quark = error_quark; + g_hash_table_insert (registered_settings, (gpointer) name, info); } static guint32 -get_priority_for_setting_type (GType type) +_get_setting_priority (NMSetting *setting) { - int i; + GHashTableIter iter; + SettingInfo *info; - for (i = 0; default_map[i].name; i++) { - if (default_map[i].type == type) - return default_map[i].priority; - } + _ensure_registered (); + g_hash_table_iter_init (&iter, registered_settings); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &info)) { + if (G_OBJECT_TYPE (setting) == info->type) + return info->priority; + } return G_MAXUINT32; } static gboolean -get_base_type_for_setting_type (GType type) +_is_setting_base_type (NMSetting *setting) { - int i; - - for (i = 0; default_map[i].name; i++) { - if (default_map[i].type == type) - return default_map[i].base_type; - } - return FALSE; + /* Historical oddity: PPPoE is a base-type even though it's not + * priority 1. It needs to be sorted *after* lower-level stuff like + * WiFi security or 802.1x for secrets, but it's still allowed as a + * base type. + */ + return _get_setting_priority (setting) == 1 || NM_IS_SETTING_PPPOE (setting); } +/*************************************************************/ + /** * nm_connection_lookup_setting_type: * @name: a setting name @@ -324,25 +240,18 @@ get_base_type_for_setting_type (GType type) GType nm_connection_lookup_setting_type (const char *name) { - char *type_name; - GType type; + SettingInfo *info; g_return_val_if_fail (name != NULL, G_TYPE_NONE); - if (!registered_settings) - register_default_settings (); + _ensure_registered (); - type_name = (char *) g_hash_table_lookup (registered_settings, name); - if (type_name) { - type = g_type_from_name (type_name); - if (!type) - g_warning ("Can not get type for '%s'.", type_name); - } else { - type = 0; - g_warning ("Unknown setting '%s'", name); - } + info = g_hash_table_lookup (registered_settings, name); + if (info) + return info->type; - return type; + g_warning ("Unknown setting '%s'", name); + return G_TYPE_INVALID; } /** @@ -357,13 +266,16 @@ nm_connection_lookup_setting_type (const char *name) GType nm_connection_lookup_setting_type_by_quark (GQuark error_quark) { - int i; + SettingInfo *info; + GHashTableIter iter; - for (i = 0; default_map[i].name; i++) { - if (default_map[i].error_quark == error_quark) - return default_map[i].type; - } + _ensure_registered (); + g_hash_table_iter_init (&iter, registered_settings); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &info)) { + if (info->error_quark == error_quark) + return info->type; + } return G_TYPE_INVALID; } @@ -739,8 +651,8 @@ nm_connection_verify (NMConnection *connection, GError **error) gpointer value; GSList *all_settings = NULL; gboolean success = TRUE; + NMSetting *base; const char *ctype; - GType base_type; if (error) g_return_val_if_fail (*error == NULL, FALSE); @@ -791,8 +703,8 @@ nm_connection_verify (NMConnection *connection, GError **error) return FALSE; } - base_type = nm_connection_lookup_setting_type (ctype); - if (base_type == 0) { + base = nm_connection_get_setting_by_name (connection, ctype); + if (!base) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID, @@ -800,7 +712,7 @@ nm_connection_verify (NMConnection *connection, GError **error) return FALSE; } - if (!get_base_type_for_setting_type (base_type)) { + if (!_is_setting_base_type (base)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID, @@ -896,8 +808,8 @@ setting_priority_compare (gconstpointer a, gconstpointer b) { guint32 prio_a, prio_b; - prio_a = get_priority_for_setting_type (G_OBJECT_TYPE (NM_SETTING (a))); - prio_b = get_priority_for_setting_type (G_OBJECT_TYPE (NM_SETTING (b))); + prio_a = _get_setting_priority (NM_SETTING (a)); + prio_b = _get_setting_priority (NM_SETTING (b)); if (prio_a < prio_b) return -1; @@ -906,14 +818,6 @@ setting_priority_compare (gconstpointer a, gconstpointer b) return 1; } -static void -add_setting_to_list (gpointer key, gpointer data, gpointer user_data) -{ - GSList **list = (GSList **) user_data; - - *list = g_slist_insert_sorted (*list, NM_SETTING (data), setting_priority_compare); -} - /** * nm_connection_need_secrets: * @connection: the #NMConnection @@ -938,9 +842,11 @@ nm_connection_need_secrets (NMConnection *connection, GPtrArray **hints) { NMConnectionPrivate *priv; + GHashTableIter hiter; GSList *settings = NULL; GSList *iter; const char *name = NULL; + NMSetting *setting; g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); @@ -950,15 +856,14 @@ nm_connection_need_secrets (NMConnection *connection, priv = NM_CONNECTION_GET_PRIVATE (connection); /* Get list of settings in priority order */ - g_hash_table_foreach (priv->settings, add_setting_to_list, &settings); + g_hash_table_iter_init (&hiter, priv->settings); + while (g_hash_table_iter_next (&hiter, NULL, (gpointer) &setting)) + settings = g_slist_insert_sorted (settings, setting, setting_priority_compare); for (iter = settings; iter; iter = g_slist_next (iter)) { - NMSetting *setting = NM_SETTING (iter->data); GPtrArray *secrets; - // FIXME: do something with requested secrets rather than asking for - // all of them. Maybe make secrets a hash table mapping - // settings name :: [list of secrets key names]. + setting = NM_SETTING (iter->data); secrets = nm_setting_need_secrets (setting); if (secrets) { if (hints) @@ -1234,14 +1139,7 @@ nm_connection_get_virtual_iface_name (NMConnection *connection) NMConnection * nm_connection_new (void) { - GObject *object; - - if (!registered_settings) - register_default_settings (); - - object = g_object_new (NM_TYPE_CONNECTION, NULL); - - return NM_CONNECTION (object); + return (NMConnection *) g_object_new (NM_TYPE_CONNECTION, NULL); } /** @@ -1405,6 +1303,23 @@ nm_connection_get_setting_bond (NMConnection *connection) } /** + * nm_connection_get_setting_bridge: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingBridge the connection might contain. + * + * Returns: (transfer none): an #NMSettingBridge if the connection contains one, otherwise NULL + **/ +NMSettingBridge * +nm_connection_get_setting_bridge (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingBridge *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BRIDGE); +} + +/** * nm_connection_get_setting_cdma: * @connection: the #NMConnection * @@ -1677,6 +1592,23 @@ nm_connection_get_setting_wireless_security (NMConnection *connection) } /** + * nm_connection_get_setting_bridge_port: + * @connection: the #NMConnection + * + * A shortcut to return any #NMSettingBridgePort the connection might contain. + * + * Returns: (transfer none): an #NMSettingBridgePort if the connection contains one, otherwise NULL + **/ +NMSettingBridgePort * +nm_connection_get_setting_bridge_port (NMConnection *connection) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + return (NMSettingBridgePort *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BRIDGE_PORT); +} + +/** * nm_connection_get_setting_vlan: * @connection: the #NMConnection * |