summary refs log tree commit diff
path: root/libnm-util
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2011-08-23 19:16:47 +0200
committerMichael Biebl <biebl@debian.org>2011-08-23 19:16:47 +0200
commit263bf4c0c89bb88dc995acd9a6a2de9095fbd461 (patch)
tree7224326afe367409e7150e49fad9029f81fe24b8 /libnm-util
parentd465e5fac63f36bcf4069e36827f4b62c494556d (diff)
Imported Upstream version 0.9.0 upstream/0.9.0
Diffstat (limited to 'libnm-util')
-rw-r--r--libnm-util/libnm-util.ver14
-rw-r--r--libnm-util/nm-connection.c75
-rw-r--r--libnm-util/nm-connection.h7
-rw-r--r--libnm-util/nm-param-spec-specialized.c6
-rw-r--r--libnm-util/nm-setting-8021x.c405
-rw-r--r--libnm-util/nm-setting-8021x.h36
-rw-r--r--libnm-util/nm-setting-bluetooth.c47
-rw-r--r--libnm-util/nm-setting-bluetooth.h26
-rw-r--r--libnm-util/nm-setting-cdma.h12
-rw-r--r--libnm-util/nm-setting-connection.c16
-rw-r--r--libnm-util/nm-setting-gsm.c109
-rw-r--r--libnm-util/nm-setting-gsm.h49
-rw-r--r--libnm-util/nm-setting-ip4-config.c431
-rw-r--r--libnm-util/nm-setting-ip4-config.h52
-rw-r--r--libnm-util/nm-setting-ip6-config.c407
-rw-r--r--libnm-util/nm-setting-ip6-config.h63
-rw-r--r--libnm-util/nm-setting-ppp.c133
-rw-r--r--libnm-util/nm-setting-ppp.h12
-rw-r--r--libnm-util/nm-setting-pppoe.c42
-rw-r--r--libnm-util/nm-setting-pppoe.h12
-rw-r--r--libnm-util/nm-setting-serial.c55
-rw-r--r--libnm-util/nm-setting-serial.h12
-rw-r--r--libnm-util/nm-setting-vpn.c191
-rw-r--r--libnm-util/nm-setting-vpn.h17
-rw-r--r--libnm-util/nm-setting-wimax.c41
-rw-r--r--libnm-util/nm-setting-wimax.h10
-rw-r--r--libnm-util/nm-setting-wired.c137
-rw-r--r--libnm-util/nm-setting-wired.h14
-rw-r--r--libnm-util/nm-setting-wireless-security.c240
-rw-r--r--libnm-util/nm-setting-wireless-security.h42
-rw-r--r--libnm-util/nm-setting-wireless.c214
-rw-r--r--libnm-util/nm-setting-wireless.h30
-rw-r--r--libnm-util/nm-setting.c121
-rw-r--r--libnm-util/nm-setting.h65
-rw-r--r--libnm-util/nm-utils.c8
-rw-r--r--libnm-util/nm-utils.h30
-rw-r--r--libnm-util/tests/test-general.c122
-rw-r--r--libnm-util/tests/test-secrets.c86
-rw-r--r--libnm-util/tests/test-setting-8021x.c3
-rw-r--r--libnm-util/tests/test-settings-defaults.c5
40 files changed, 3169 insertions, 228 deletions
diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver
index 4ff0838e..6052c275 100644
--- a/libnm-util/libnm-util.ver
+++ b/libnm-util/libnm-util.ver
@@ -94,10 +94,15 @@ global:
 	nm_ip6_route_set_next_hop;
 	nm_ip6_route_set_prefix;
 	nm_ip6_route_unref;
+	nm_setting_802_1x_add_altsubject_match;
 	nm_setting_802_1x_add_eap_method;
+	nm_setting_802_1x_add_phase2_altsubject_match;
+	nm_setting_802_1x_clear_altsubject_matches;
 	nm_setting_802_1x_clear_eap_methods;
+	nm_setting_802_1x_clear_phase2_altsubject_matches;
 	nm_setting_802_1x_error_get_type;
 	nm_setting_802_1x_error_quark;
+	nm_setting_802_1x_get_altsubject_match;
 	nm_setting_802_1x_get_anonymous_identity;
 	nm_setting_802_1x_get_ca_cert_blob;
 	nm_setting_802_1x_get_ca_cert_path;
@@ -108,12 +113,15 @@ global:
 	nm_setting_802_1x_get_client_cert_scheme;
 	nm_setting_802_1x_get_eap_method;
 	nm_setting_802_1x_get_identity;
+	nm_setting_802_1x_get_num_altsubject_matches;
 	nm_setting_802_1x_get_num_eap_methods;
+	nm_setting_802_1x_get_num_phase2_altsubject_matches;
 	nm_setting_802_1x_get_password;
 	nm_setting_802_1x_get_password_flags;
 	nm_setting_802_1x_get_phase1_fast_provisioning;
 	nm_setting_802_1x_get_phase1_peaplabel;
 	nm_setting_802_1x_get_phase1_peapver;
+	nm_setting_802_1x_get_phase2_altsubject_match;
 	nm_setting_802_1x_get_phase2_auth;
 	nm_setting_802_1x_get_phase2_autheap;
 	nm_setting_802_1x_get_phase2_ca_cert_blob;
@@ -129,6 +137,7 @@ global:
 	nm_setting_802_1x_get_phase2_private_key_password_flags;
 	nm_setting_802_1x_get_phase2_private_key_path;
 	nm_setting_802_1x_get_phase2_private_key_scheme;
+	nm_setting_802_1x_get_phase2_subject_match;
 	nm_setting_802_1x_get_pin;
 	nm_setting_802_1x_get_pin_flags;
 	nm_setting_802_1x_get_private_key_blob;
@@ -137,10 +146,13 @@ global:
 	nm_setting_802_1x_get_private_key_password_flags;
 	nm_setting_802_1x_get_private_key_path;
 	nm_setting_802_1x_get_private_key_scheme;
+	nm_setting_802_1x_get_subject_match;
 	nm_setting_802_1x_get_system_ca_certs;
 	nm_setting_802_1x_get_type;
 	nm_setting_802_1x_new;
+	nm_setting_802_1x_remove_altsubject_match;
 	nm_setting_802_1x_remove_eap_method;
+	nm_setting_802_1x_remove_phase2_altsubject_match;
 	nm_setting_802_1x_set_ca_cert;
 	nm_setting_802_1x_set_client_cert;
 	nm_setting_802_1x_set_phase2_ca_cert;
@@ -342,6 +354,7 @@ global:
 	nm_setting_wired_get_cloned_mac_address;
 	nm_setting_wired_get_duplex;
 	nm_setting_wired_get_mac_address;
+	nm_setting_wired_get_mac_address_blacklist;
 	nm_setting_wired_get_mtu;
 	nm_setting_wired_get_num_s390_options;
 	nm_setting_wired_get_port;
@@ -362,6 +375,7 @@ global:
 	nm_setting_wireless_get_channel;
 	nm_setting_wireless_get_cloned_mac_address;
 	nm_setting_wireless_get_mac_address;
+	nm_setting_wireless_get_mac_address_blacklist;
 	nm_setting_wireless_get_mode;
 	nm_setting_wireless_get_mtu;
 	nm_setting_wireless_get_num_seen_bssids;
diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c
index 6e9f92b5..91fc3afa 100644
--- a/libnm-util/nm-connection.c
+++ b/libnm-util/nm-connection.c
@@ -99,6 +99,7 @@ nm_connection_error_get_type (void)
 			ENUM_ENTRY (NM_CONNECTION_ERROR_UNKNOWN, "UnknownError"),
 			ENUM_ENTRY (NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND, "ConnectionSettingNotFound"),
 			ENUM_ENTRY (NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID, "ConnectionTypeInvalid"),
+			ENUM_ENTRY (NM_CONNECTION_ERROR_SETTING_NOT_FOUND, "SettingNotFound"),
 			{ 0, 0, 0 }
 		};
 		etype = g_enum_register_static ("NMConnectionError", values);
@@ -790,60 +791,76 @@ nm_connection_verify (NMConnection *connection, GError **error)
  * nm_connection_update_secrets:
  * @connection: the #NMConnection
  * @setting_name: the setting object name to which the secrets apply
- * @setting_secrets: (element-type utf8 GObject.Value): a #GHashTable mapping
+ * @secrets: (element-type utf8 GObject.Value): a #GHashTable mapping
  * string:#GValue of setting property names and secrets of the given @setting_name
  * @error: location to store error, or %NULL
  *
  * Update the specified setting's secrets, given a hash table of secrets
  * intended for that setting (deserialized from D-Bus for example).  Will also
  * extract the given setting's secrets hash if given a hash of hashes, as would
- * be returned from nm_connection_to_hash().
+ * be returned from nm_connection_to_hash().  If @setting_name is %NULL, expects
+ * a fully serialized #NMConnection as returned by nm_connection_to_hash() and
+ * will update all secrets from all settings contained in @secrets.
  *
- * Returns: %TRUE if the secrets were successfully updated and the connection
- * is valid, %FALSE on failure or if the setting was never added to the connection
+ * Returns: %TRUE if the secrets were successfully updated, %FALSE if the update
+ * failed (tried to update secrets for a setting that doesn't exist, etc)
  **/
 gboolean
 nm_connection_update_secrets (NMConnection *connection,
                               const char *setting_name,
-                              GHashTable *setting_secrets,
+                              GHashTable *secrets,
                               GError **error)
 {
 	NMSetting *setting;
 	gboolean success;
 	GHashTable *tmp;
-	GType setting_type;
 
 	g_return_val_if_fail (connection != NULL, FALSE);
 	g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
-	g_return_val_if_fail (setting_name != NULL, FALSE);
-	g_return_val_if_fail (setting_secrets != NULL, FALSE);
+	g_return_val_if_fail (secrets != NULL, FALSE);
 	if (error)
 		g_return_val_if_fail (*error == NULL, FALSE);
 
-	setting_type = nm_connection_lookup_setting_type (setting_name);
-	if (!setting_type) {
-		g_set_error_literal (error,
-		                     NM_CONNECTION_ERROR,
-		                     NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND,
-		                     setting_name);
-		return FALSE;
-	}
+	if (setting_name) {
+		/* Update just one setting */
+		setting = nm_connection_get_setting_by_name (connection, setting_name);
+		if (!setting) {
+			g_set_error_literal (error,
+				                 NM_CONNECTION_ERROR,
+				                 NM_CONNECTION_ERROR_SETTING_NOT_FOUND,
+				                 setting_name);
+			return FALSE;
+		}
 
-	setting = nm_connection_get_setting (connection, setting_type);
-	if (!setting) {
-		g_set_error_literal (error,
-		                     NM_CONNECTION_ERROR,
-		                     NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND,
-		                     setting_name);
-		return FALSE;
-	}
+		/* Check if this is a hash of hashes, ie a full deserialized connection,
+		 * not just a single hashed setting.
+		 */
+		tmp = g_hash_table_lookup (secrets, setting_name);
+		success = nm_setting_update_secrets (setting, tmp ? tmp : secrets, error);
+	} else {
+		GHashTableIter iter;
+		const char *name;
 
-	/* Check if this is a hash of hashes, ie a full deserialized connection,
-	 * not just a single hashed setting.
-	 */
-	tmp = g_hash_table_lookup (setting_secrets, setting_name);
+		success = TRUE; /* Just in case 'secrets' has no elements */
+
+		/* Try as a serialized connection (GHashTable of GHashTables) */
+		g_hash_table_iter_init (&iter, secrets);
+		while (g_hash_table_iter_next (&iter, (gpointer) &name, (gpointer) &tmp)) {
+			setting = nm_connection_get_setting_by_name (connection, name);
+			if (!setting) {
+				g_set_error_literal (error,
+						             NM_CONNECTION_ERROR,
+						             NM_CONNECTION_ERROR_SETTING_NOT_FOUND,
+						             name);
+				return FALSE;
+			}
 
-	success = nm_setting_update_secrets (setting, tmp ? tmp : setting_secrets, error);
+			/* Update the secrets for this setting */
+			success = nm_setting_update_secrets (setting, tmp, error);
+			if (success == FALSE)
+				break;
+		}
+	}
 	if (success)
 		g_signal_emit (connection, signals[SECRETS_UPDATED], 0, setting_name);
 	return success;
diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h
index 87b053c1..3cd18747 100644
--- a/libnm-util/nm-connection.h
+++ b/libnm-util/nm-connection.h
@@ -66,6 +66,8 @@ G_BEGIN_DECLS
  *   'connection' setting did not point to a valid connection base type; ie
  *   it was not a hardware-related setting like #NMSettingWired or
  *   #NMSettingWireless.
+ * @NM_CONNECTION_ERROR_SETTING_NOT_FOUND: the #NMConnection object
+ *   did not contain the specified #NMSetting object
  *
  * Describes errors that may result from operations involving a #NMConnection.
  *
@@ -74,7 +76,8 @@ typedef enum
 {
 	NM_CONNECTION_ERROR_UNKNOWN = 0,
 	NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND,
-	NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID
+	NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID,
+	NM_CONNECTION_ERROR_SETTING_NOT_FOUND
 } NMConnectionError;
 
 #define NM_TYPE_CONNECTION_ERROR (nm_connection_error_get_type ()) 
@@ -146,7 +149,7 @@ void          nm_connection_clear_secrets (NMConnection *connection);
 
 gboolean      nm_connection_update_secrets (NMConnection *connection,
                                             const char *setting_name,
-                                            GHashTable *setting_secrets,
+                                            GHashTable *secrets,
                                             GError **error);
 
 void          nm_connection_set_path      (NMConnection *connection,
diff --git a/libnm-util/nm-param-spec-specialized.c b/libnm-util/nm-param-spec-specialized.c
index 93623a11..7e921bca 100644
--- a/libnm-util/nm-param-spec-specialized.c
+++ b/libnm-util/nm-param-spec-specialized.c
@@ -230,7 +230,7 @@ _gvalue_destroy (gpointer data)
 }
 
 static GValue *
-nm_gvalue_dup (const GValue *value)
+_gvalue_dup (const GValue *value)
 {
 	GValue *dup;
 
@@ -246,7 +246,7 @@ iterate_collection (const GValue *value, gpointer user_data)
 {
 	GSList **list = (GSList **) user_data;
 	
-	*list = g_slist_prepend (*list, nm_gvalue_dup (value));
+	*list = g_slist_prepend (*list, _gvalue_dup (value));
 }
 
 static gint
@@ -306,7 +306,7 @@ iterate_map (const GValue *key_val,
 {
 	GHashTable **hash = (GHashTable **) user_data;
 
-	g_hash_table_insert (*hash, g_value_dup_string (key_val), nm_gvalue_dup (value_val));
+	g_hash_table_insert (*hash, g_value_dup_string (key_val), _gvalue_dup (value_val));
 }
 
 typedef struct {
diff --git a/libnm-util/nm-setting-8021x.c b/libnm-util/nm-setting-8021x.c
index 24750422..07fdcc21 100644
--- a/libnm-util/nm-setting-8021x.c
+++ b/libnm-util/nm-setting-8021x.c
@@ -116,6 +116,8 @@ typedef struct {
 	char *anonymous_identity;
 	GByteArray *ca_cert;
 	char *ca_path;
+	char *subject_match;
+	GSList *altsubject_matches;
 	GByteArray *client_cert;
 	char *phase1_peapver;
 	char *phase1_peaplabel;
@@ -124,6 +126,8 @@ typedef struct {
 	char *phase2_autheap;
 	GByteArray *phase2_ca_cert;
 	char *phase2_ca_path;
+	char *phase2_subject_match;
+	GSList *phase2_altsubject_matches;
 	GByteArray *phase2_client_cert;
 	char *password;
 	NMSettingSecretFlags password_flags;
@@ -145,6 +149,8 @@ enum {
 	PROP_ANONYMOUS_IDENTITY,
 	PROP_CA_CERT,
 	PROP_CA_PATH,
+	PROP_SUBJECT_MATCH,
+	PROP_ALTSUBJECT_MATCHES,
 	PROP_CLIENT_CERT,
 	PROP_PHASE1_PEAPVER,
 	PROP_PHASE1_PEAPLABEL,
@@ -153,6 +159,8 @@ enum {
 	PROP_PHASE2_AUTHEAP,
 	PROP_PHASE2_CA_CERT,
 	PROP_PHASE2_CA_PATH,
+	PROP_PHASE2_SUBJECT_MATCH,
+	PROP_PHASE2_ALTSUBJECT_MATCHES,
 	PROP_PHASE2_CLIENT_CERT,
 	PROP_PASSWORD,
 	PROP_PASSWORD_FLAGS,
@@ -557,6 +565,135 @@ nm_setting_802_1x_set_ca_cert (NMSetting8021x *self,
 }
 
 /**
+ * nm_setting_802_1x_get_subject_match:
+ * @setting: the #NMSetting8021x
+ *
+ * Returns: the #NMSetting8021x:subject-match property. This is the
+ * substring to be matched against the subject of the authentication
+ * server certificate, or NULL no subject verification is to be
+ * performed.
+ **/
+const char *
+nm_setting_802_1x_get_subject_match (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	return NM_SETTING_802_1X_GET_PRIVATE (setting)->subject_match;
+}
+
+/**
+ * nm_setting_802_1x_get_num_altsubject_matches:
+ * @setting: the #NMSetting8021x
+ *
+ * Returns the number of entries in the
+ * #NMSetting8021x:altsubject-matches property of this setting.
+ *
+ * Returns: the number of altsubject-matches entries.
+ **/
+guint32
+nm_setting_802_1x_get_num_altsubject_matches (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), 0);
+
+	return g_slist_length (NM_SETTING_802_1X_GET_PRIVATE (setting)->altsubject_matches);
+}
+
+/**
+ * nm_setting_802_1x_get_altsubject_match:
+ * @setting: the #NMSettingConnection
+ * @i: the zero-based index of the array of altSubjectName matches
+ *
+ * Returns the altSubjectName match at index @i.
+ *
+ * Returns: the altSubjectName match at index @i
+ **/
+const char *
+nm_setting_802_1x_get_altsubject_match (NMSetting8021x *setting, guint32 i)
+{
+	NMSetting8021xPrivate *priv;
+
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
+	g_return_val_if_fail (i <= g_slist_length (priv->altsubject_matches), NULL);
+
+	return (const char *) g_slist_nth_data (priv->altsubject_matches, i);
+}
+
+/**
+ * nm_setting_802_1x_add_altsubject_match:
+ * @setting: the #NMSetting8021x
+ * @altsubject_match: the altSubjectName to allow for this connection
+ *
+ * Adds an allowed alternate subject name match.  Until at least one
+ * match is added, the altSubjectName of the remote authentication
+ * server is not verified.
+ *
+ * Returns: TRUE if the alternative subject name match was
+ *  successfully added, FALSE if it was already allowed.
+ **/
+gboolean
+nm_setting_802_1x_add_altsubject_match (NMSetting8021x *setting,
+										const char *altsubject_match)
+{
+	NMSetting8021xPrivate *priv;
+	GSList *iter;
+
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE);
+	g_return_val_if_fail (altsubject_match != NULL, FALSE);
+
+	priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
+	for (iter = priv->altsubject_matches; iter; iter = g_slist_next (iter)) {
+		if (!strcmp (altsubject_match, (char *) iter->data))
+			return FALSE;
+	}
+
+	priv->altsubject_matches = g_slist_append (priv->altsubject_matches, g_strdup (altsubject_match));
+	return TRUE;
+}
+
+/**
+ * nm_setting_802_1x_remove_altsubject_match:
+ * @setting: the #NMSetting8021x
+ * @i: the index of the altSubjectName match to remove
+ *
+ * Removes the allowed altSubjectName at the specified index.
+ **/
+void
+nm_setting_802_1x_remove_altsubject_match (NMSetting8021x *setting, guint32 i)
+{
+	NMSetting8021xPrivate *priv;
+	GSList *elt;
+
+	g_return_if_fail (NM_IS_SETTING_802_1X (setting));
+
+	priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
+	elt = g_slist_nth (priv->altsubject_matches, i);
+	g_return_if_fail (elt != NULL);
+
+	g_free (elt->data);
+	priv->altsubject_matches = g_slist_delete_link (priv->altsubject_matches, elt);
+}
+
+/**
+ * nm_setting_802_1x_clear_altsubject_matches:
+ * @setting: the #NMSetting8021x
+ *
+ * Clears all altSubjectName matches.
+ **/
+void
+nm_setting_802_1x_clear_altsubject_matches (NMSetting8021x *setting)
+{
+	NMSetting8021xPrivate *priv;
+
+	g_return_if_fail (NM_IS_SETTING_802_1X (setting));
+
+	priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
+	nm_utils_slist_free (priv->altsubject_matches, g_free);
+	priv->altsubject_matches = NULL;
+}
+
+/**
  * nm_setting_802_1x_get_client_cert_scheme:
  * @setting: the #NMSetting8021x
  *
@@ -968,6 +1105,137 @@ nm_setting_802_1x_set_phase2_ca_cert (NMSetting8021x *self,
 }
 
 /**
+ * nm_setting_802_1x_get_phase2_subject_match:
+ * @setting: the #NMSetting8021x
+ *
+ * Returns: the #NMSetting8021x:phase2-subject-match property. This is
+ * the substring to be matched against the subject of the "phase 2"
+ * authentication server certificate, or NULL no subject verification
+ * is to be performed.
+ **/
+const char *
+nm_setting_802_1x_get_phase2_subject_match (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_subject_match;
+}
+
+/**
+ * nm_setting_802_1x_get_num_phase2_altsubject_matches:
+ * @setting: the #NMSetting8021x
+ *
+ * Returns the number of entries in the
+ * #NMSetting8021x:phase2-altsubject-matches property of this setting.
+ *
+ * Returns: the number of phase2-altsubject-matches entries.
+ **/
+guint32
+nm_setting_802_1x_get_num_phase2_altsubject_matches (NMSetting8021x *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), 0);
+
+	return g_slist_length (NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_altsubject_matches);
+}
+
+/**
+ * nm_setting_802_1x_get_phase2_altsubject_match:
+ * @setting: the #NMSettingConnection
+ * @i: the zero-based index of the array of "phase 2" altSubjectName matches
+ *
+ * Returns the "phase 2" altSubjectName match at index @i.
+ *
+ * Returns: the "phase 2" altSubjectName match at index @i
+ **/
+const char *
+nm_setting_802_1x_get_phase2_altsubject_match (NMSetting8021x *setting, guint32 i)
+{
+	NMSetting8021xPrivate *priv;
+
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
+
+	priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
+	g_return_val_if_fail (i <= g_slist_length (priv->phase2_altsubject_matches), NULL);
+
+	return (const char *) g_slist_nth_data (priv->phase2_altsubject_matches, i);
+}
+
+/**
+ * nm_setting_802_1x_add_phase2_altsubject_match:
+ * @setting: the #NMSetting8021x
+ * @phase2_altsubject_match: the "phase 2" altSubjectName to allow for this
+ * connection
+ *
+ * Adds an allowed alternate subject name match for "phase 2".  Until
+ * at least one match is added, the altSubjectName of the "phase 2"
+ * remote authentication server is not verified.
+ *
+ * Returns: TRUE if the "phase 2" alternative subject name match was
+ *  successfully added, FALSE if it was already allowed.
+ **/
+gboolean
+nm_setting_802_1x_add_phase2_altsubject_match (NMSetting8021x *setting,
+											   const char *phase2_altsubject_match)
+{
+	NMSetting8021xPrivate *priv;
+	GSList *iter;
+
+	g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE);
+	g_return_val_if_fail (phase2_altsubject_match != NULL, FALSE);
+
+	priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
+	for (iter = priv->phase2_altsubject_matches; iter; iter = g_slist_next (iter)) {
+		if (!strcmp (phase2_altsubject_match, (char *) iter->data))
+			return FALSE;
+	}
+
+	priv->phase2_altsubject_matches = g_slist_append (priv->altsubject_matches,
+													  g_strdup (phase2_altsubject_match));
+	return TRUE;
+}
+
+/**
+ * nm_setting_802_1x_remove_phase2_altsubject_match:
+ * @setting: the #NMSetting8021x
+ * @i: the index of the "phase 2" altSubjectName match to remove
+ *
+ * Removes the allowed "phase 2" altSubjectName at the specified index.
+ **/
+void
+nm_setting_802_1x_remove_phase2_altsubject_match (NMSetting8021x *setting, guint32 i)
+{
+	NMSetting8021xPrivate *priv;
+	GSList *elt;
+
+	g_return_if_fail (NM_IS_SETTING_802_1X (setting));
+
+	priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
+	elt = g_slist_nth (priv->phase2_altsubject_matches, i);
+	g_return_if_fail (elt != NULL);
+
+	g_free (elt->data);
+	priv->phase2_altsubject_matches = g_slist_delete_link (priv->phase2_altsubject_matches, elt);
+}
+
+/**
+ * nm_setting_802_1x_clear_phase2_altsubject_matches:
+ * @setting: the #NMSetting8021x
+ *
+ * Clears all "phase 2" altSubjectName matches.
+ **/
+void
+nm_setting_802_1x_clear_phase2_altsubject_matches (NMSetting8021x *setting)
+{
+	NMSetting8021xPrivate *priv;
+
+	g_return_if_fail (NM_IS_SETTING_802_1X (setting));
+
+	priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
+	nm_utils_slist_free (priv->phase2_altsubject_matches, g_free);
+	priv->phase2_altsubject_matches = NULL;
+}
+
+/**
  * nm_setting_802_1x_get_phase2_client_cert_scheme:
  * @setting: the #NMSetting8021x
  *
@@ -1396,8 +1664,7 @@ nm_setting_802_1x_set_private_key (NMSetting8021x *self,
  * @setting: the #NMSetting8021x
  *
  * Returns: the private key password used to decrypt the private key if
- *  previously set with nm_setting_802_1x_set_private_key_from_file(),
- *  nm_setting_802_1x_set_private_key_path(), or the
+ *  previously set with nm_setting_802_1x_set_private_key(), or the
  *  #NMSetting8021x:private-key-password property.
  **/
 const char *
@@ -1470,8 +1737,7 @@ nm_setting_802_1x_get_private_key_format (NMSetting8021x *setting)
  * @setting: the #NMSetting8021x
  *
  * Returns: the private key password used to decrypt the private key if
- *  previously set with nm_setting_802_1x_set_phase2_private_key_from_file(),
- *  nm_setting_802_1x_set_phase2_private_key_path(), or the
+ *  previously set with nm_setting_802_1x_set_phase2_private_key() or the
  *  #NMSetting8021x:phase2-private-key-password property.
  **/
 const char *
@@ -2267,15 +2533,19 @@ finalize (GObject *object)
 	g_free (priv->identity);
 	g_free (priv->anonymous_identity);
 	g_free (priv->ca_path);
+	g_free (priv->subject_match);
 	g_free (priv->phase1_peapver);
 	g_free (priv->phase1_peaplabel);
 	g_free (priv->phase1_fast_provisioning);
 	g_free (priv->phase2_auth);
 	g_free (priv->phase2_autheap);
 	g_free (priv->phase2_ca_path);
+	g_free (priv->phase2_subject_match);
 	g_free (priv->password);
 
 	nm_utils_slist_free (priv->eap, g_free);
+	nm_utils_slist_free (priv->altsubject_matches, g_free);
+	nm_utils_slist_free (priv->phase2_altsubject_matches, g_free);
 
 	if (priv->ca_cert)
 		g_byte_array_free (priv->ca_cert, TRUE);
@@ -2350,6 +2620,14 @@ set_property (GObject *object, guint prop_id,
 		g_free (priv->ca_path);
 		priv->ca_path = g_value_dup_string (value);
 		break;
+	case PROP_SUBJECT_MATCH:
+		g_free (priv->subject_match);
+		priv->subject_match = g_value_dup_string (value);
+		break;
+	case PROP_ALTSUBJECT_MATCHES:
+		nm_utils_slist_free (priv->altsubject_matches, g_free);
+		priv->altsubject_matches = g_value_dup_boxed (value);
+		break;
 	case PROP_CLIENT_CERT:
 		if (priv->client_cert) {
 			g_byte_array_free (priv->client_cert, TRUE);
@@ -2398,6 +2676,14 @@ set_property (GObject *object, guint prop_id,
 		g_free (priv->phase2_ca_path);
 		priv->phase2_ca_path = g_value_dup_string (value);
 		break;
+	case PROP_PHASE2_SUBJECT_MATCH:
+		g_free (priv->phase2_subject_match);
+		priv->phase2_subject_match = g_value_dup_string (value);
+		break;
+	case PROP_PHASE2_ALTSUBJECT_MATCHES:
+		nm_utils_slist_free (priv->phase2_altsubject_matches, g_free);
+		priv->phase2_altsubject_matches = g_value_dup_boxed (value);
+		break;
 	case PROP_PHASE2_CLIENT_CERT:
 		if (priv->phase2_client_cert) {
 			g_byte_array_free (priv->phase2_client_cert, TRUE);
@@ -2487,6 +2773,12 @@ get_property (GObject *object, guint prop_id,
 	case PROP_CA_PATH:
 		g_value_set_string (value, priv->ca_path);
 		break;
+	case PROP_SUBJECT_MATCH:
+		g_value_set_string (value, priv->subject_match);
+		break;
+	case PROP_ALTSUBJECT_MATCHES:
+		g_value_set_boxed (value, priv->altsubject_matches);
+		break;
 	case PROP_CLIENT_CERT:
 		g_value_set_boxed (value, priv->client_cert);
 		break;
@@ -2511,6 +2803,12 @@ get_property (GObject *object, guint prop_id,
 	case PROP_PHASE2_CA_PATH:
 		g_value_set_string (value, priv->phase2_ca_path);
 		break;
+	case PROP_PHASE2_SUBJECT_MATCH:
+		g_value_set_string (value, priv->phase2_subject_match);
+		break;
+	case PROP_PHASE2_ALTSUBJECT_MATCHES:
+		g_value_set_boxed (value, priv->phase2_altsubject_matches);
+		break;
 	case PROP_PHASE2_CLIENT_CERT:
 		g_value_set_boxed (value, priv->phase2_client_cert);
 		break;
@@ -2669,6 +2967,47 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class)
 						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
 
 	/**
+	 * NMSetting8021x:subject-match:
+	 *
+	 * Substring to be matched against the subject of the certificate
+	 * presented by the authentication server. When unset, no
+	 * verification of the authentication server certificate's subject
+	 * is performed.
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_SUBJECT_MATCH,
+		 g_param_spec_string (NM_SETTING_802_1X_SUBJECT_MATCH,
+							  "Subject match",
+							  "Substring to be matched against the subject of "
+							  "the certificate presented by the authentication "
+							  "server. When unset, no verification of the "
+							  "authentication server certificate's subject is "
+							  "performed.",
+							  NULL,
+							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	/**
+	 * NMSetting8021x:altsubject-matches:
+	 *
+	 * List of strings to be matched against the altSubjectName of the
+	 * certificate presented by the authentication server. If the list
+	 * is empty, no verification of the server certificate's
+	 * altSubjectName is performed.
+	 **/
+	 g_object_class_install_property
+		 (object_class, PROP_ALTSUBJECT_MATCHES,
+		  _nm_param_spec_specialized (NM_SETTING_802_1X_ALTSUBJECT_MATCHES,
+									  "altSubjectName matches",
+									  "List of strings to be matched against "
+									  "the altSubjectName of the certificate "
+									  "presented by the authentication server. "
+									  "If the list is empty, no verification "
+									  "of the server certificate's "
+									  "altSubjectName is performed.",
+									  DBUS_TYPE_G_LIST_OF_STRING,
+									  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	/**
 	 * NMSetting8021x:client-cert:
 	 *
 	 * Contains the client certificate if used by the EAP method specified in
@@ -2861,6 +3200,51 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class)
 						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
 
 	/**
+	 * NMSetting8021x:phase2-subject-match:
+	 *
+	 * Substring to be matched against the subject of the certificate
+	 * presented by the authentication server during the inner "phase
+	 * 2" authentication. When unset, no verification of the
+	 * authentication server certificate's subject is performed.
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_PHASE2_SUBJECT_MATCH,
+		 g_param_spec_string (NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH,
+							  "Phase2 subject match",
+							  "Substring to be matched against the subject of "
+							  "the certificate presented by the authentication "
+							  "server during the inner 'phase2' "
+							  "authentication. When unset, no verification of "
+							  "the authentication server certificate's subject "
+							  "is performed.",
+							  NULL,
+							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	/**
+	 * NMSetting8021x:phase2-altsubject-matches:
+	 *
+	 * List of strings to be matched against the altSubjectName of the
+	 * certificate presented by the authentication server during the
+	 * inner "phase 2" authentication. If the list is empty, no
+	 * verification of the server certificate's altSubjectName is
+	 * performed.
+	 **/
+	 g_object_class_install_property
+		 (object_class, PROP_PHASE2_ALTSUBJECT_MATCHES,
+		  _nm_param_spec_specialized (NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES,
+									  "altSubjectName matches",
+									  "List of strings to be matched against "
+									  "List of strings to be matched against "
+									  "the altSubjectName of the certificate "
+									  "presented by the authentication server "
+									  "during the inner 'phase 2' "
+									  "authentication. If the list is empty, no "
+									  "verification of the server certificate's "
+									  "altSubjectName is performed.",
+									  DBUS_TYPE_G_LIST_OF_STRING,
+									  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	/**
 	 * NMSetting8021x:phase2-client-cert:
 	 *
 	 * Contains the client certificate if used by the EAP method specified in
@@ -2874,7 +3258,7 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class)
 							   "Phase2 client certificate",
 							   "Contains the 'phase 2' client certificate if "
 							   "used by the EAP method specified in the "
-							   "'phase2-eap' or 'phase2-autheap' properties. "
+							   "'phase2-auth' or 'phase2-autheap' properties. "
 							   "Certificate data is specified using a 'scheme'; "
 							   "two are currently supported: blob and path.  "
 							   "When using the blob scheme (which is backwards "
@@ -2998,8 +3382,8 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class)
 	 *
 	 * Private key data used by "phase 2" inner authentication methods.
 	 *
-	 * Contains the "phase 2" inner private key if the #NMSetting8021x:auth or
-	 * #NMSetting8021x:phase2-autheap property is set to 'tls'.  Setting this
+	 * Contains the "phase 2" inner private key if the #NMSetting8021x:phase2-auth
+	 * or #NMSetting8021x:phase2-autheap property is set to 'tls'.  Setting this
 	 * property directly is discouraged; use the
 	 * nm_setting_802_1x_set_phase2_private_key() function instead.
 	 **/
@@ -3008,7 +3392,7 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class)
 		 _nm_param_spec_specialized (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
 							   "Phase2 private key",
 							   "Contains the 'phase 2' inner private key when "
-							   "the 'phase2-eap' or 'phase2-autheap' property "
+							   "the 'phase2-auth' or 'phase2-autheap' property "
 							   "is set to 'tls'.  Key data is specified using a "
 							   "'scheme'; two are currently supported: blob and "
 							   "path. When using the blob scheme and private "
@@ -3077,9 +3461,8 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class)
 	 * #NMSetting8021x:phase2-ca-path properties using the system CA directory
 	 * specified at configure time with the --system-ca-path switch.  The
 	 * certificates in this directory are added to the verification chain in
-	 * addition to any certificates specified by the #NMSetting8021x:ca-cert,
-	 * #NMSetting8021x:ca-cert-path, #NMSetting8021x:phase2-ca-cert and
-	 * #NMSetting8021x:phase2-ca-cert-path properties.
+	 * addition to any certificates specified by the #NMSetting8021x:ca-cert
+	 * and #NMSetting8021x:phase2-ca-cert properties.
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_SYSTEM_CA_CERTS,
diff --git a/libnm-util/nm-setting-8021x.h b/libnm-util/nm-setting-8021x.h
index f3e61e55..a6016aea 100644
--- a/libnm-util/nm-setting-8021x.h
+++ b/libnm-util/nm-setting-8021x.h
@@ -78,8 +78,14 @@ typedef enum {
 
 #define NM_SETTING_802_1X_SETTING_NAME "802-1x"
 
-typedef enum
-{
+/**
+ * NMSetting8021xError:
+ * @NM_SETTING_802_1X_ERROR_UNKNOWN: unknown or unclassified error
+ * @NM_SETTING_802_1X_ERROR_INVALID_PROPERTY: the property was invalid
+ * @NM_SETTING_802_1X_ERROR_MISSING_PROPERTY: the property was missing and is
+ * required
+ */
+typedef enum {
 	NM_SETTING_802_1X_ERROR_UNKNOWN = 0,
 	NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
 	NM_SETTING_802_1X_ERROR_MISSING_PROPERTY
@@ -97,6 +103,8 @@ GQuark nm_setting_802_1x_error_quark (void);
 #define NM_SETTING_802_1X_ANONYMOUS_IDENTITY "anonymous-identity"
 #define NM_SETTING_802_1X_CA_CERT "ca-cert"
 #define NM_SETTING_802_1X_CA_PATH "ca-path"
+#define NM_SETTING_802_1X_SUBJECT_MATCH "subject-match"
+#define NM_SETTING_802_1X_ALTSUBJECT_MATCHES "altsubject-matches"
 #define NM_SETTING_802_1X_CLIENT_CERT "client-cert"
 #define NM_SETTING_802_1X_PHASE1_PEAPVER "phase1-peapver"
 #define NM_SETTING_802_1X_PHASE1_PEAPLABEL "phase1-peaplabel"
@@ -105,6 +113,8 @@ GQuark nm_setting_802_1x_error_quark (void);
 #define NM_SETTING_802_1X_PHASE2_AUTHEAP "phase2-autheap"
 #define NM_SETTING_802_1X_PHASE2_CA_CERT "phase2-ca-cert"
 #define NM_SETTING_802_1X_PHASE2_CA_PATH "phase2-ca-path"
+#define NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH "phase2-subject-match"
+#define NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES "phase2-altsubject-matches"
 #define NM_SETTING_802_1X_PHASE2_CLIENT_CERT "phase2-client-cert"
 #define NM_SETTING_802_1X_PASSWORD "password"
 #define NM_SETTING_802_1X_PASSWORD_FLAGS "password-flags"
@@ -179,6 +189,17 @@ gboolean               nm_setting_802_1x_set_ca_cert                 (NMSetting8
                                                                       NMSetting8021xCKFormat *out_format,
                                                                       GError **error);
 
+const char *      nm_setting_802_1x_get_subject_match                (NMSetting8021x *setting);
+
+guint32           nm_setting_802_1x_get_num_altsubject_matches       (NMSetting8021x *setting);
+const char *      nm_setting_802_1x_get_altsubject_match             (NMSetting8021x *setting,
+																	  guint32 i);
+gboolean          nm_setting_802_1x_add_altsubject_match             (NMSetting8021x *setting,
+																	  const char *altsubject_match);
+void              nm_setting_802_1x_remove_altsubject_match          (NMSetting8021x *setting,
+																	  guint32 i);
+void              nm_setting_802_1x_clear_altsubject_matches         (NMSetting8021x *setting);
+
 NMSetting8021xCKScheme nm_setting_802_1x_get_client_cert_scheme      (NMSetting8021x *setting);
 const GByteArray *     nm_setting_802_1x_get_client_cert_blob        (NMSetting8021x *setting);
 const char *           nm_setting_802_1x_get_client_cert_path        (NMSetting8021x *setting);
@@ -207,6 +228,17 @@ gboolean               nm_setting_802_1x_set_phase2_ca_cert          (NMSetting8
                                                                       NMSetting8021xCKFormat *out_format,
                                                                       GError **error);
 
+const char *      nm_setting_802_1x_get_phase2_subject_match         (NMSetting8021x *setting);
+
+guint32           nm_setting_802_1x_get_num_phase2_altsubject_matches   (NMSetting8021x *setting);
+const char *      nm_setting_802_1x_get_phase2_altsubject_match         (NMSetting8021x *setting,
+																		 guint32 i);
+gboolean          nm_setting_802_1x_add_phase2_altsubject_match         (NMSetting8021x *setting,
+																		 const char *phase2_altsubject_match);
+void              nm_setting_802_1x_remove_phase2_altsubject_match      (NMSetting8021x *setting,
+																		 guint32 i);
+void              nm_setting_802_1x_clear_phase2_altsubject_matches     (NMSetting8021x *setting);
+
 NMSetting8021xCKScheme nm_setting_802_1x_get_phase2_client_cert_scheme   (NMSetting8021x *setting);
 const GByteArray *     nm_setting_802_1x_get_phase2_client_cert_blob     (NMSetting8021x *setting);
 const char *           nm_setting_802_1x_get_phase2_client_cert_path     (NMSetting8021x *setting);
diff --git a/libnm-util/nm-setting-bluetooth.c b/libnm-util/nm-setting-bluetooth.c
index e3cebe2e..1b1178b2 100644
--- a/libnm-util/nm-setting-bluetooth.c
+++ b/libnm-util/nm-setting-bluetooth.c
@@ -34,6 +34,24 @@
 #include "nm-setting-cdma.h"
 #include "nm-setting-gsm.h"
 
+/**
+ * SECTION:nm-setting-bluetooth
+ * @short_description: Describes Bluetooth connection properties
+ * @include: nm-setting-bluetooth.h
+ *
+ * The #NMSettingBluetooth object is a #NMSetting subclass that describes
+ * properties necessary for connection to devices that provide network
+ * connections via the Bluetooth Dial-Up Networking (DUN) and Network Access
+ * Point (NAP) profiles.
+ **/
+
+/**
+ * nm_setting_bluetooth_error_quark:
+ *
+ * Registers an error quark for #NMSettingBluetooth if necessary.
+ *
+ * Returns: the error quark used for #NMSettingBluetooth errors.
+ **/
 GQuark
 nm_setting_bluetooth_error_quark (void)
 {
@@ -83,11 +101,27 @@ enum {
 	LAST_PROP
 };
 
+/**
+ * nm_setting_bluetooth_new:
+ *
+ * Creates a new #NMSettingBluetooth object with default values.
+ *
+ * Returns: (transfer full): the new empty #NMSettingBluetooth object
+ **/
 NMSetting *nm_setting_bluetooth_new (void)
 {
 	return (NMSetting *) g_object_new (NM_TYPE_SETTING_BLUETOOTH, NULL);
 }
 
+/**
+ * nm_setting_bluetooth_get_connection_type:
+ * @setting: the #NMSettingBluetooth
+ *
+ * Returns the connection method for communicating with the remote device (i.e.
+ * either DUN to a DUN-capable device or PANU to a NAP-capable device).
+ *
+ * Returns: the type, either %NM_SETTING_BLUETOOTH_PANU or %NM_SETTING_BLUETOOTH_DUN
+ **/
 const char *
 nm_setting_bluetooth_get_connection_type (NMSettingBluetooth *setting)
 {
@@ -96,6 +130,15 @@ nm_setting_bluetooth_get_connection_type (NMSettingBluetooth *setting)
 	return NM_SETTING_BLUETOOTH_GET_PRIVATE (setting)->type;
 }
 
+/**
+ * nm_setting_bluetooth_get_bdaddr:
+ * @setting: the #NMSettingBluetooth
+ *
+ * Gets the Bluetooth address of the remote device which this setting
+ * describes a connection to.
+ *
+ * Returns: the Bluetooth address
+ **/
 const GByteArray *
 nm_setting_bluetooth_get_bdaddr (NMSettingBluetooth *setting)
 {
@@ -266,8 +309,8 @@ nm_setting_bluetooth_class_init (NMSettingBluetoothClass *setting_class)
 	/**
 	 * NMSettingBluetooth:type:
 	 *
-	 * Either 'dun' for Dial-Up Networking connections (not yet supported) or
-	 * 'panu' for Personal Area Networking connections.
+	 * Either 'dun' for Dial-Up Networking connections or 'panu' for Personal
+	 * Area Networking connections to devices supporting the NAP profile.
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_TYPE,
diff --git a/libnm-util/nm-setting-bluetooth.h b/libnm-util/nm-setting-bluetooth.h
index e41183bc..a17a72bf 100644
--- a/libnm-util/nm-setting-bluetooth.h
+++ b/libnm-util/nm-setting-bluetooth.h
@@ -40,8 +40,17 @@ G_BEGIN_DECLS
 
 #define NM_SETTING_BLUETOOTH_SETTING_NAME "bluetooth"
 
-typedef enum
-{
+/**
+ * NMSettingBluetoothError:
+ * @NM_SETTING_BLUETOOTH_ERROR_UNKNOWN: unknown or unclassified error
+ * @NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY: the property was invalid
+ * @NM_SETTING_BLUETOOTH_ERROR_MISSING_PROPERTY: the property was missing and is
+ * required
+ * @NM_SETTING_BLUETOOTH_ERROR_TYPE_SETTING_NOT_FOUND: the connection
+ * did not contain a required type setting, ie for DUN connections the connection
+ * must also contain an #NMSettingGsm or #NMSettingCdma as appropriate
+ */
+typedef enum {
 	NM_SETTING_BLUETOOTH_ERROR_UNKNOWN = 0,
 	NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
 	NM_SETTING_BLUETOOTH_ERROR_MISSING_PROPERTY,
@@ -57,7 +66,20 @@ GQuark nm_setting_bluetooth_error_quark (void);
 #define NM_SETTING_BLUETOOTH_BDADDR    "bdaddr"
 #define NM_SETTING_BLUETOOTH_TYPE      "type"
 
+/**
+ * NM_SETTING_BLUETOOTH_TYPE_DUN:
+ *
+ * Connection type describing a connection to devices that support the Bluetooth
+ * DUN profile.
+ */
 #define NM_SETTING_BLUETOOTH_TYPE_DUN  "dun"
+
+/**
+ * NM_SETTING_BLUETOOTH_TYPE_PANU:
+ *
+ * Connection type describing a connection to devices that support the Bluetooth
+ * NAP (Network Access Point) protocol, which accepts connections via PANU.
+ */
 #define NM_SETTING_BLUETOOTH_TYPE_PANU "panu"
 
 typedef struct {
diff --git a/libnm-util/nm-setting-cdma.h b/libnm-util/nm-setting-cdma.h
index 8abfce4a..d0a5de4c 100644
--- a/libnm-util/nm-setting-cdma.h
+++ b/libnm-util/nm-setting-cdma.h
@@ -39,8 +39,16 @@ G_BEGIN_DECLS
 
 #define NM_SETTING_CDMA_SETTING_NAME "cdma"
 
-typedef enum
-{
+/**
+ * NMSettingCdmaError:
+ * @NM_SETTING_CDMA_ERROR_UNKNOWN: unknown or unclassified error
+ * @NM_SETTING_CDMA_ERROR_INVALID_PROPERTY: the property was invalid
+ * @NM_SETTING_CDMA_ERROR_MISSING_PROPERTY: the property was missing and is
+ * required
+ * @NM_SETTING_CDMA_ERROR_MISSING_SERIAL_SETTING: the required #NMSettingSerial
+ * is missing in the connection
+ */
+typedef enum {
 	NM_SETTING_CDMA_ERROR_UNKNOWN = 0,
 	NM_SETTING_CDMA_ERROR_INVALID_PROPERTY,
 	NM_SETTING_CDMA_ERROR_MISSING_PROPERTY,
diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c
index b3bf4443..e9030b10 100644
--- a/libnm-util/nm-setting-connection.c
+++ b/libnm-util/nm-setting-connection.c
@@ -562,6 +562,21 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
 	return TRUE;
 }
 
+static gboolean
+compare_property (NMSetting *setting,
+                  NMSetting *other,
+                  const GParamSpec *prop_spec,
+                  NMSettingCompareFlags flags)
+{
+	/* Handle ignore ID */
+	if (   (flags & NM_SETTING_COMPARE_FLAG_IGNORE_ID)
+	    && g_strcmp0 (prop_spec->name, NM_SETTING_CONNECTION_ID) == 0)
+		return TRUE;
+
+	/* Otherwise chain up to parent to handle generic compare */
+	return NM_SETTING_CLASS (nm_setting_connection_parent_class)->compare_property (setting, other, prop_spec, flags);
+}
+
 static void
 nm_setting_connection_init (NMSettingConnection *setting)
 {
@@ -693,6 +708,7 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class)
 	object_class->get_property = get_property;
 	object_class->finalize     = finalize;
 	parent_class->verify       = verify;
+	parent_class->compare_property = compare_property;
 
 	/* Properties */
 
diff --git a/libnm-util/nm-setting-gsm.c b/libnm-util/nm-setting-gsm.c
index 0ece448b..7033541b 100644
--- a/libnm-util/nm-setting-gsm.c
+++ b/libnm-util/nm-setting-gsm.c
@@ -29,6 +29,23 @@
 #include "nm-utils.h"
 #include "nm-setting-private.h"
 
+/**
+ * SECTION:nm-setting-gsm
+ * @short_description: Describes GSM/3GPP-based mobile broadband properties
+ * @include: nm-setting-gsm.h
+ *
+ * The #NMSettingGsm object is a #NMSetting subclass that describes
+ * properties that allow connections to 3GPP-based mobile broadband
+ * networks, including those using GPRS/EDGE and UMTS/HSPA technology.
+ */
+
+/**
+ * nm_setting_gsm_error_quark:
+ *
+ * Registers an error quark for #NMSettingGsm if necessary.
+ *
+ * Returns: the error quark used for #NMSettingGsm errors.
+ **/
 GQuark
 nm_setting_gsm_error_quark (void)
 {
@@ -103,12 +120,25 @@ enum {
 	LAST_PROP
 };
 
+/**
+ * nm_setting_gsm_new:
+ *
+ * Creates a new #NMSettingGsm object with default values.
+ *
+ * Returns: the new empty #NMSettingGsm object
+ **/
 NMSetting *
 nm_setting_gsm_new (void)
 {
 	return (NMSetting *) g_object_new (NM_TYPE_SETTING_GSM, NULL);
 }
 
+/**
+ * nm_setting_gsm_get_number:
+ * @setting: the #NMSettingGsm
+ *
+ * Returns: the #NMSettingGsm:number property of the setting
+ **/
 const char *
 nm_setting_gsm_get_number (NMSettingGsm *setting)
 {
@@ -117,6 +147,12 @@ nm_setting_gsm_get_number (NMSettingGsm *setting)
 	return NM_SETTING_GSM_GET_PRIVATE (setting)->number;
 }
 
+/**
+ * nm_setting_gsm_get_username:
+ * @setting: the #NMSettingGsm
+ *
+ * Returns: the #NMSettingGsm:username property of the setting
+ **/
 const char *
 nm_setting_gsm_get_username (NMSettingGsm *setting)
 {
@@ -125,6 +161,12 @@ nm_setting_gsm_get_username (NMSettingGsm *setting)
 	return NM_SETTING_GSM_GET_PRIVATE (setting)->username;
 }
 
+/**
+ * nm_setting_gsm_get_password:
+ * @setting: the #NMSettingGsm
+ *
+ * Returns: the #NMSettingGsm:password property of the setting
+ **/
 const char *
 nm_setting_gsm_get_password (NMSettingGsm *setting)
 {
@@ -147,6 +189,12 @@ nm_setting_gsm_get_password_flags (NMSettingGsm *setting)
 	return NM_SETTING_GSM_GET_PRIVATE (setting)->password_flags;
 }
 
+/**
+ * nm_setting_gsm_get_apn:
+ * @setting: the #NMSettingGsm
+ *
+ * Returns: the #NMSettingGsm:apn property of the setting
+ **/
 const char *
 nm_setting_gsm_get_apn (NMSettingGsm *setting)
 {
@@ -155,6 +203,12 @@ nm_setting_gsm_get_apn (NMSettingGsm *setting)
 	return NM_SETTING_GSM_GET_PRIVATE (setting)->apn;
 }
 
+/**
+ * nm_setting_gsm_get_network_id:
+ * @setting: the #NMSettingGsm
+ *
+ * Returns: the #NMSettingGsm:network-id property of the setting
+ **/
 const char *
 nm_setting_gsm_get_network_id (NMSettingGsm *setting)
 {
@@ -163,6 +217,12 @@ nm_setting_gsm_get_network_id (NMSettingGsm *setting)
 	return NM_SETTING_GSM_GET_PRIVATE (setting)->network_id;
 }
 
+/**
+ * nm_setting_gsm_get_network_type:
+ * @setting: the #NMSettingGsm
+ *
+ * Returns: the #NMSettingGsm:network-type property of the setting
+ **/
 int
 nm_setting_gsm_get_network_type (NMSettingGsm *setting)
 {
@@ -171,6 +231,12 @@ nm_setting_gsm_get_network_type (NMSettingGsm *setting)
 	return NM_SETTING_GSM_GET_PRIVATE (setting)->network_type;
 }
 
+/**
+ * nm_setting_gsm_get_allowed_bands:
+ * @setting: the #NMSettingGsm
+ *
+ * Returns: the #NMSettingGsm:allowed-bands property of the setting
+ **/
 guint32
 nm_setting_gsm_get_allowed_bands (NMSettingGsm *setting)
 {
@@ -179,6 +245,12 @@ nm_setting_gsm_get_allowed_bands (NMSettingGsm *setting)
 	return NM_SETTING_GSM_GET_PRIVATE (setting)->allowed_bands;
 }
 
+/**
+ * nm_setting_gsm_get_pin:
+ * @setting: the #NMSettingGsm
+ *
+ * Returns: the #NMSettingGsm:pin property of the setting
+ **/
 const char *
 nm_setting_gsm_get_pin (NMSettingGsm *setting)
 {
@@ -201,6 +273,12 @@ nm_setting_gsm_get_pin_flags (NMSettingGsm *setting)
 	return NM_SETTING_GSM_GET_PRIVATE (setting)->pin_flags;
 }
 
+/**
+ * nm_setting_gsm_get_home_only:
+ * @setting: the #NMSettingGsm
+ *
+ * Returns: the #NMSettingGsm:home-only property of the setting
+ **/
 gboolean
 nm_setting_gsm_get_home_only (NMSettingGsm *setting)
 {
@@ -481,19 +559,20 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class)
 	 * NMSettingGsm:number:
 	 *
 	 * Number to dial when establishing a PPP data session with the GSM-based
-	 * mobile broadband network.  In most cases, leave the number blank and a
-	 * number selecting the APN specified in the 'apn' property will be used
-	 * automatically when required.
+	 * mobile broadband network.  Many modems do not require PPP for connections
+	 * to the mobile network and thus this property should be left blank, which
+	 * allows NetworkManager to select the appropriate settings automatically.
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_NUMBER,
 		 g_param_spec_string (NM_SETTING_GSM_NUMBER,
 						  "Number",
-						  "Number to dial when establishing a PPP data session "
-						  "with the GSM-based mobile broadband network.  In most "
-						  "cases, leave the number blank and a number selecting "
-						  "the APN specified in the 'apn' property will be used "
-						  "automatically when required.",
+		                  "Number to dial when establishing a PPP data session "
+		                  "with the GSM-based mobile broadband network.  Many "
+		                  "modems do not require PPP for connections to the "
+		                  "mobile network and thus this property should be left "
+		                  "blank, which allows NetworkManager to select the "
+		                  "appropriate settings automatically.",
 						  NULL,
 						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
 
@@ -599,9 +678,9 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class)
 	 * NMSettingGsm:network-type:
 	 *
 	 * Network preference to force the device to only use specific network
-	 * technologies.  The permitted values are: -1: any, 0: 3G only,
-	 * 1: GPRS/EDGE only, 2: prefer 3G, and 3: prefer 2G.  Note that not all
-	 * devices allow network preference control.
+	 * technologies.  Permitted values are those specified by
+	 * #NMSettingGsmNetworkType.  Note that not all devices allow network
+	 * preference control.
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_NETWORK_TYPE,
@@ -621,7 +700,8 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class)
 	 * NMSettingGsm:allowed-bands:
 	 *
 	 * Bitfield of allowed frequency bands.  Note that not all devices allow
-	 * frequency band control.
+	 * frequency band control.  Permitted values are those specified by
+	 * #NMSettingGsmNetworkBand.
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_ALLOWED_BANDS,
@@ -643,7 +723,8 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class)
 		                     || NM_SETTING_GSM_BAND_U850
 		                     || NM_SETTING_GSM_BAND_U900
 		                     || NM_SETTING_GSM_BAND_U17IX
-		                     || NM_SETTING_GSM_BAND_U1900,
+		                     || NM_SETTING_GSM_BAND_U1900
+		                     || NM_SETTING_GSM_BAND_U2600,
 		                    NM_SETTING_GSM_BAND_ANY,
 		                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
 
@@ -667,7 +748,7 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class)
 	/**
 	 * NMSettingGsm:pin-flags:
 	 *
-	 * Flags indicating how to handle #NMSettingGsm:pin:.
+	 * Flags indicating how to handle #NMSettingGsm:pin.
 	 **/
 	g_object_class_install_property (object_class, PROP_PIN_FLAGS,
 		 g_param_spec_uint (NM_SETTING_GSM_PIN_FLAGS,
diff --git a/libnm-util/nm-setting-gsm.h b/libnm-util/nm-setting-gsm.h
index 855787c2..6459a4ab 100644
--- a/libnm-util/nm-setting-gsm.h
+++ b/libnm-util/nm-setting-gsm.h
@@ -39,8 +39,16 @@ G_BEGIN_DECLS
 
 #define NM_SETTING_GSM_SETTING_NAME "gsm"
 
-typedef enum
-{
+/**
+ * NMSettingGsmError:
+ * @NM_SETTING_GSM_ERROR_UNKNOWN: unknown or unclassified error
+ * @NM_SETTING_GSM_ERROR_INVALID_PROPERTY: the property was invalid
+ * @NM_SETTING_GSM_ERROR_MISSING_PROPERTY: the property was missing and is
+ * required
+ * @NM_SETTING_GSM_ERROR_MISSING_SERIAL_SETTING: the required #NMSettingSerial
+ * is missing in the connection
+ */
+typedef enum {
 	NM_SETTING_GSM_ERROR_UNKNOWN = 0,
 	NM_SETTING_GSM_ERROR_INVALID_PROPERTY,
 	NM_SETTING_GSM_ERROR_MISSING_PROPERTY,
@@ -65,6 +73,21 @@ GQuark nm_setting_gsm_error_quark (void);
 #define NM_SETTING_GSM_PIN_FLAGS      "pin-flags"
 #define NM_SETTING_GSM_HOME_ONLY      "home-only"
 
+/**
+ * NMSettingGsmNetworkType:
+ * @NM_SETTING_GSM_NETWORK_TYPE_ANY: any access technology may be used
+ * @NM_SETTING_GSM_NETWORK_TYPE_UMTS_HSPA: only 3G-type (UMTS and HSPA)
+ * technologies may be used
+ * @NM_SETTING_GSM_NETWORK_TYPE_GPRS_EDGE: only 2G-type (GPRS and EDGE)
+ * technologies may be used
+ * @NM_SETTING_GSM_NETWORK_TYPE_PREFER_UMTS_HSPA: 3G-type technologies are
+ * preferred but 2G-type technologies may be used as a fallback
+ * @NM_SETTING_GSM_NETWORK_TYPE_PREFER_GPRS_EDGE: 2G-type technologies are
+ * preferred but 3G-type technologies may be used as a fallback
+ *
+ * #NMSettingGsmNetworkType values indicate the allowed access technologies
+ * the device may use when connecting to this network.
+ */
 typedef enum {
 	NM_SETTING_GSM_NETWORK_TYPE_ANY = -1,
 	NM_SETTING_GSM_NETWORK_TYPE_UMTS_HSPA = 0,
@@ -73,6 +96,27 @@ typedef enum {
 	NM_SETTING_GSM_NETWORK_TYPE_PREFER_GPRS_EDGE = 3
 } NMSettingGsmNetworkType;
 
+/**
+ * NMSettingGsmNetworkBand:
+ * @NM_SETTING_GSM_BAND_UNKNOWN: unknown or no band specified
+ * @NM_SETTING_GSM_BAND_ANY: any band is allowed
+ * @NM_SETTING_GSM_BAND_EGSM: 900 MHz original GSM band
+ * @NM_SETTING_GSM_BAND_DCS: 1800 MHz DCS band
+ * @NM_SETTING_GSM_BAND_PCS: US 1900 MHz PCS band
+ * @NM_SETTING_GSM_BAND_G850: US 850 MHz Cellular band
+ * @NM_SETTING_GSM_BAND_U2100: WCDMA 3GPP UMTS 2100 MHz (Class I)
+ * @NM_SETTING_GSM_BAND_U1800: WCDMA 3GPP UMTS 1800 MHz (Class III)
+ * @NM_SETTING_GSM_BAND_U17IV: WCDMA 3GPP AWS 1700/2100 MHz (Class IV)
+ * @NM_SETTING_GSM_BAND_U800: WCDMA 3GPP UMTS 800 MHz (Class VI)
+ * @NM_SETTING_GSM_BAND_U850: WCDMA 3GPP UMTS 850 MHz (Class V)
+ * @NM_SETTING_GSM_BAND_U900: WCDMA 3GPP UMTS 900 MHz (Class VIII)
+ * @NM_SETTING_GSM_BAND_U17IX: WCDMA 3GPP UMTS 1700 MHz (Class IX)
+ * @NM_SETTING_GSM_BAND_U1900: WCDMA 3GPP UMTS 1900 MHz (Class II)
+ * @NM_SETTING_GSM_BAND_U2600: WCDMA 3GPP UMTS 2600 MHz (Class VII, internal)
+ *
+ * #NMSettingGsmNetworkBand values indicate the allowed frequency bands
+ * the device may use when connecting to this network.
+ */
 typedef enum {
 	NM_SETTING_GSM_BAND_UNKNOWN      = 0x00000000,
 	NM_SETTING_GSM_BAND_ANY          = 0x00000001,
@@ -88,6 +132,7 @@ typedef enum {
 	NM_SETTING_GSM_BAND_U900         = 0x00000400, /* WCDMA 3GPP UMTS 900 MHz      (Class VIII) */
 	NM_SETTING_GSM_BAND_U17IX        = 0x00000800, /* WCDMA 3GPP UMTS 1700 MHz     (Class IX) */
 	NM_SETTING_GSM_BAND_U1900        = 0x00001000, /* WCDMA 3GPP UMTS 1900 MHz     (Class II) */
+	NM_SETTING_GSM_BAND_U2600        = 0x00002000, /* WCDMA 3GPP UMTS 2600 MHz     (Class VII, internal) */
 } NMSettingGsmNetworkBand;
 
 typedef struct {
diff --git a/libnm-util/nm-setting-ip4-config.c b/libnm-util/nm-setting-ip4-config.c
index 6961050d..6b164ea8 100644
--- a/libnm-util/nm-setting-ip4-config.c
+++ b/libnm-util/nm-setting-ip4-config.c
@@ -31,6 +31,22 @@
 #include "nm-utils.h"
 #include "nm-dbus-glib-types.h"
 
+/**
+ * SECTION:nm-setting-ip4-config
+ * @short_description: Describes IPv4 addressing, routing, and name service properties
+ * @include: nm-setting-ip4-config.h
+ *
+ * The #NMSettingIP4Config object is a #NMSetting subclass that describes
+ * properties related to IPv4 addressing, routing, and Domain Name Service
+ **/
+
+/**
+ * nm_setting_ip4_config_error_quark:
+ *
+ * Registers an error quark for #NMSettingIP4Config if necessary.
+ *
+ * Returns: the error quark used for #NMSettingIP4Config errors.
+ **/
 GQuark
 nm_setting_ip4_config_error_quark (void)
 {
@@ -108,12 +124,25 @@ enum {
 	LAST_PROP
 };
 
+/**
+ * nm_setting_ip4_config_new:
+ *
+ * Creates a new #NMSettingIP4Config object with default values.
+ *
+ * Returns: (transfer full): the new empty #NMSettingIP4Config object
+ **/
 NMSetting *
 nm_setting_ip4_config_new (void)
 {
 	return (NMSetting *) g_object_new (NM_TYPE_SETTING_IP4_CONFIG, NULL);
 }
 
+/**
+ * nm_setting_ip4_config_get_method:
+ * @setting: the #NMSettingIP4Config
+ *
+ * Returns: the #NMSettingIP4Config:method property of the setting
+ **/
 const char *
 nm_setting_ip4_config_get_method (NMSettingIP4Config *setting)
 {
@@ -122,6 +151,12 @@ nm_setting_ip4_config_get_method (NMSettingIP4Config *setting)
 	return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->method;
 }
 
+/**
+ * nm_setting_ip4_config_get_num_dns:
+ * @setting: the #NMSettingIP4Config
+ *
+ * Returns: the number of configured DNS servers
+ **/
 guint32
 nm_setting_ip4_config_get_num_dns (NMSettingIP4Config *setting)
 {
@@ -130,6 +165,14 @@ nm_setting_ip4_config_get_num_dns (NMSettingIP4Config *setting)
 	return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->dns->len;
 }
 
+/**
+ * nm_setting_ip4_config_get_dns:
+ * @setting: the #NMSettingIP4Config
+ * @i: index number of the DNS server to return
+ *
+ * Returns: the IPv4 address (network byte order) of the DNS server at index
+ * @i
+ **/
 guint32
 nm_setting_ip4_config_get_dns (NMSettingIP4Config *setting, guint32 i)
 {
@@ -143,6 +186,16 @@ nm_setting_ip4_config_get_dns (NMSettingIP4Config *setting, guint32 i)
 	return g_array_index (priv->dns, guint32, i);
 }
 
+/**
+ * nm_setting_ip4_config_add_dns:
+ * @setting: the #NMSettingIP4Config
+ * @dns: the IPv4 address (network byte order) of the DNS server to add
+ *
+ * Adds a new DNS server to the setting.
+ *
+ * Returns: %TRUE if the DNS server was added; %FALSE if the server was already
+ * known
+ **/
 gboolean
 nm_setting_ip4_config_add_dns (NMSettingIP4Config *setting, guint32 dns)
 {
@@ -161,6 +214,13 @@ nm_setting_ip4_config_add_dns (NMSettingIP4Config *setting, guint32 dns)
 	return TRUE;
 }
 
+/**
+ * nm_setting_ip4_config_remove_dns:
+ * @setting: the #NMSettingIP4Config
+ * @i: index number of the DNS server to remove
+ *
+ * Removes the DNS server at index @i.
+ **/
 void
 nm_setting_ip4_config_remove_dns (NMSettingIP4Config *setting, guint32 i)
 {
@@ -174,6 +234,12 @@ nm_setting_ip4_config_remove_dns (NMSettingIP4Config *setting, guint32 i)
 	g_array_remove_index (priv->dns, i);
 }
 
+/**
+ * nm_setting_ip4_config_clear_dns:
+ * @setting: the #NMSettingIP4Config
+ *
+ * Removes all configured DNS servers.
+ **/
 void
 nm_setting_ip4_config_clear_dns (NMSettingIP4Config *setting)
 {
@@ -185,6 +251,12 @@ nm_setting_ip4_config_clear_dns (NMSettingIP4Config *setting)
 	g_array_remove_range (priv->dns, 0, priv->dns->len);
 }
 
+/**
+ * nm_setting_ip4_config_get_num_dns_searches:
+ * @setting: the #NMSettingIP4Config
+ *
+ * Returns: the number of configured DNS search domains
+ **/
 guint32
 nm_setting_ip4_config_get_num_dns_searches (NMSettingIP4Config *setting)
 {
@@ -193,6 +265,13 @@ nm_setting_ip4_config_get_num_dns_searches (NMSettingIP4Config *setting)
 	return g_slist_length (NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->dns_search);
 }
 
+/**
+ * nm_setting_ip4_config_get_dns_search:
+ * @setting: the #NMSettingIP4Config
+ * @i: index number of the DNS search domain to return
+ *
+ * Returns: the DNS search domain at index @i
+ **/
 const char *
 nm_setting_ip4_config_get_dns_search (NMSettingIP4Config *setting, guint32 i)
 {
@@ -206,6 +285,16 @@ nm_setting_ip4_config_get_dns_search (NMSettingIP4Config *setting, guint32 i)
 	return (const char *) g_slist_nth_data (priv->dns_search, i);
 }
 
+/**
+ * nm_setting_ip4_config_add_dns_search:
+ * @setting: the #NMSettingIP4Config
+ * @dns_search: the search domain to add
+ *
+ * Adds a new DNS search domain to the setting.
+ *
+ * Returns: %TRUE if the DNS search domain was added; %FALSE if the search
+ * domain was already known
+ **/
 gboolean
 nm_setting_ip4_config_add_dns_search (NMSettingIP4Config *setting,
                                       const char *dns_search)
@@ -227,6 +316,13 @@ nm_setting_ip4_config_add_dns_search (NMSettingIP4Config *setting,
 	return TRUE;
 }
 
+/**
+ * nm_setting_ip4_config_remove_dns_search:
+ * @setting: the #NMSettingIP4Config
+ * @i: index number of the DNS search domain
+ *
+ * Removes the DNS search domain at index @i.
+ **/
 void
 nm_setting_ip4_config_remove_dns_search (NMSettingIP4Config *setting, guint32 i)
 {
@@ -243,6 +339,12 @@ nm_setting_ip4_config_remove_dns_search (NMSettingIP4Config *setting, guint32 i)
 	priv->dns_search = g_slist_delete_link (priv->dns_search, elt);
 }
 
+/**
+ * nm_setting_ip4_config_clear_dns_searches:
+ * @setting: the #NMSettingIP4Config
+ *
+ * Removes all configured DNS search domains.
+ **/
 void
 nm_setting_ip4_config_clear_dns_searches (NMSettingIP4Config *setting)
 {
@@ -252,6 +354,12 @@ nm_setting_ip4_config_clear_dns_searches (NMSettingIP4Config *setting)
 	NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->dns_search = NULL;
 }
 
+/**
+ * nm_setting_ip4_config_get_num_addresses:
+ * @setting: the #NMSettingIP4Config
+ *
+ * Returns: the number of configured addresses
+ **/
 guint32
 nm_setting_ip4_config_get_num_addresses (NMSettingIP4Config *setting)
 {
@@ -260,6 +368,13 @@ nm_setting_ip4_config_get_num_addresses (NMSettingIP4Config *setting)
 	return g_slist_length (NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->addresses);
 }
 
+/**
+ * nm_setting_ip4_config_get_address:
+ * @setting: the #NMSettingIP4Config
+ * @i: index number of the address to return
+ *
+ * Returns: the address at index @i
+ **/
 NMIP4Address *
 nm_setting_ip4_config_get_address (NMSettingIP4Config *setting, guint32 i)
 {
@@ -273,6 +388,17 @@ nm_setting_ip4_config_get_address (NMSettingIP4Config *setting, guint32 i)
 	return (NMIP4Address *) g_slist_nth_data (priv->addresses, i);
 }
 
+/**
+ * nm_setting_ip4_config_add_address:
+ * @setting: the #NMSettingIP4Config
+ * @address: the new address to add
+ *
+ * Adds a new IPv4 address and associated information to the setting.  The
+ * given address is duplicated internally and is not changed by this function.
+ *
+ * Returns: %TRUE if the address was added; %FALSE if the address was already
+ * known.
+ **/
 gboolean
 nm_setting_ip4_config_add_address (NMSettingIP4Config *setting,
                                    NMIP4Address *address)
@@ -297,6 +423,13 @@ nm_setting_ip4_config_add_address (NMSettingIP4Config *setting,
 	return TRUE;
 }
 
+/**
+ * nm_setting_ip4_config_remove_address:
+ * @setting: the #NMSettingIP4Config
+ * @i: index number of the address to remove
+ *
+ * Removes the address at index @i.
+ **/
 void
 nm_setting_ip4_config_remove_address (NMSettingIP4Config *setting, guint32 i)
 {
@@ -313,6 +446,12 @@ nm_setting_ip4_config_remove_address (NMSettingIP4Config *setting, guint32 i)
 	priv->addresses = g_slist_delete_link (priv->addresses, elt);
 }
 
+/**
+ * nm_setting_ip4_config_clear_addresses:
+ * @setting: the #NMSettingIP4Config
+ *
+ * Removes all configured addresses.
+ **/
 void
 nm_setting_ip4_config_clear_addresses (NMSettingIP4Config *setting)
 {
@@ -324,6 +463,12 @@ nm_setting_ip4_config_clear_addresses (NMSettingIP4Config *setting)
 	priv->addresses = NULL;
 }
 
+/**
+ * nm_setting_ip4_config_get_num_routes:
+ * @setting: the #NMSettingIP4Config
+ *
+ * Returns: the number of configured routes
+ **/
 guint32
 nm_setting_ip4_config_get_num_routes (NMSettingIP4Config *setting)
 {
@@ -332,6 +477,13 @@ nm_setting_ip4_config_get_num_routes (NMSettingIP4Config *setting)
 	return g_slist_length (NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->routes);
 }
 
+/**
+ * nm_setting_ip4_config_get_route:
+ * @setting: the #NMSettingIP4Config
+ * @i: index number of the route to return
+ *
+ * Returns: the route at index @i
+ **/
 NMIP4Route *
 nm_setting_ip4_config_get_route (NMSettingIP4Config *setting, guint32 i)
 {
@@ -345,6 +497,16 @@ nm_setting_ip4_config_get_route (NMSettingIP4Config *setting, guint32 i)
 	return (NMIP4Route *) g_slist_nth_data (priv->routes, i);
 }
 
+/**
+ * nm_setting_ip4_config_add_route:
+ * @setting: the #NMSettingIP4Config
+ * @route: the route to add
+ *
+ * Adds a new IPv4 route and associated information to the setting.  The
+ * given route is duplicated internally and is not changed by this function.
+ *
+ * Returns: %TRUE if the route was added; %FALSE if the route was already known.
+ **/
 gboolean
 nm_setting_ip4_config_add_route (NMSettingIP4Config *setting,
                                  NMIP4Route *route)
@@ -369,6 +531,13 @@ nm_setting_ip4_config_add_route (NMSettingIP4Config *setting,
 	return TRUE;
 }
 
+/**
+ * nm_setting_ip4_config_remove_route:
+ * @setting: the #NMSettingIP4Config
+ * @i: index number of the route
+ *
+ * Removes the route at index @i.
+ **/
 void
 nm_setting_ip4_config_remove_route (NMSettingIP4Config *setting, guint32 i)
 {
@@ -385,6 +554,12 @@ nm_setting_ip4_config_remove_route (NMSettingIP4Config *setting, guint32 i)
 	priv->routes = g_slist_delete_link (priv->routes, elt);
 }
 
+/**
+ * nm_setting_ip4_config_clear_routes:
+ * @setting: the #NMSettingIP4Config
+ *
+ * Removes all configured routes.
+ **/
 void
 nm_setting_ip4_config_clear_routes (NMSettingIP4Config *setting)
 {
@@ -396,6 +571,16 @@ nm_setting_ip4_config_clear_routes (NMSettingIP4Config *setting)
 	priv->routes = NULL;
 }
 
+/**
+ * nm_setting_ip4_config_get_ignore_auto_routes:
+ * @setting: the #NMSettingIP4Config
+ *
+ * Returns the value contained in the #NMSettingIP4Config:ignore-auto-routes
+ * property.
+ *
+ * Returns: %TRUE if automatically configured (ie via DHCP) routes should be
+ * ignored.
+ **/
 gboolean
 nm_setting_ip4_config_get_ignore_auto_routes (NMSettingIP4Config *setting)
 {
@@ -404,6 +589,16 @@ nm_setting_ip4_config_get_ignore_auto_routes (NMSettingIP4Config *setting)
 	return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->ignore_auto_routes;
 }
 
+/**
+ * nm_setting_ip4_config_get_ignore_auto_dns:
+ * @setting: the #NMSettingIP4Config
+ *
+ * Returns the value contained in the #NMSettingIP4Config:ignore-auto-dns
+ * property.
+ *
+ * Returns: %TRUE if automatically configured (ie via DHCP) DNS information
+ * should be ignored.
+ **/
 gboolean
 nm_setting_ip4_config_get_ignore_auto_dns (NMSettingIP4Config *setting)
 {
@@ -412,6 +607,16 @@ nm_setting_ip4_config_get_ignore_auto_dns (NMSettingIP4Config *setting)
 	return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->ignore_auto_dns;
 }
 
+/**
+ * nm_setting_ip4_config_get_dhcp_client_id:
+ * @setting: the #NMSettingIP4Config
+ *
+ * Returns the value contained in the #NMSettingIP4Config:dhcp-client-id
+ * property.
+ *
+ * Returns: the configured Client ID to send to the DHCP server when requesting
+ * addresses via DHCP.
+ **/
 const char *
 nm_setting_ip4_config_get_dhcp_client_id (NMSettingIP4Config *setting)
 {
@@ -420,6 +625,17 @@ nm_setting_ip4_config_get_dhcp_client_id (NMSettingIP4Config *setting)
 	return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->dhcp_client_id;
 }
 
+/**
+ * nm_setting_ip4_config_get_dhcp_send_hostname:
+ * @setting: the #NMSettingIP4Config
+ *
+ * Returns the value contained in the #NMSettingIP4Config:dhcp-send-hostname
+ * property.
+ *
+ * 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.
+ **/
 gboolean
 nm_setting_ip4_config_get_dhcp_send_hostname (NMSettingIP4Config *setting)
 {
@@ -428,6 +644,15 @@ nm_setting_ip4_config_get_dhcp_send_hostname (NMSettingIP4Config *setting)
 	return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->dhcp_send_hostname;
 }
 
+/**
+ * nm_setting_ip4_config_get_dhcp_hostname:
+ * @setting: the #NMSettingIP4Config
+ *
+ * Returns the value contained in the #NMSettingIP4Config:dhcp-hostname
+ * property.
+ *
+ * Returns: the configured hostname to send to the DHCP server
+ **/
 const char *
 nm_setting_ip4_config_get_dhcp_hostname (NMSettingIP4Config *setting)
 {
@@ -436,6 +661,16 @@ nm_setting_ip4_config_get_dhcp_hostname (NMSettingIP4Config *setting)
 	return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->dhcp_hostname;
 }
 
+/**
+ * nm_setting_ip4_config_get_never_default:
+ * @setting: the #NMSettingIP4Config
+ *
+ * Returns the value contained in the #NMSettingIP4Config:never-default
+ * property.
+ *
+ * Returns: %TRUE if this connection should never be the default connection
+ * for IPv4 addressing
+ **/
 gboolean
 nm_setting_ip4_config_get_never_default (NMSettingIP4Config *setting)
 {
@@ -444,6 +679,16 @@ nm_setting_ip4_config_get_never_default (NMSettingIP4Config *setting)
 	return NM_SETTING_IP4_CONFIG_GET_PRIVATE (setting)->never_default;
 }
 
+/**
+ * nm_setting_ip4_config_get_may_fail:
+ * @setting: the #NMSettingIP4Config
+ *
+ * Returns the value contained in the #NMSettingIP4Config:may-fail
+ * property.
+ *
+ * Returns: %TRUE if this connection doesn't require IPv4 addressing to complete
+ * for the connection to succeed.
+ **/
 gboolean
 nm_setting_ip4_config_get_may_fail (NMSettingIP4Config *setting)
 {
@@ -1023,6 +1268,13 @@ struct NMIP4Address {
 	guint32 gateway;   /* network byte order */
 };
 
+/**
+ * nm_ip4_address_new:
+ *
+ * Creates and returns a new #NMIP4Address object.
+ *
+ * Returns: (transfer full): the new empty #NMIP4Address object
+ **/
 NMIP4Address *
 nm_ip4_address_new (void)
 {
@@ -1033,6 +1285,14 @@ nm_ip4_address_new (void)
 	return address;
 }
 
+/**
+ * nm_ip4_address_dup:
+ * @source: the #NMIP4Address object to copy
+ *
+ * Copies a given #NMIP4Address object and returns the copy.
+ *
+ * Returns: (transfer full): the copy of the given #NMIP4Address copy
+ **/
 NMIP4Address *
 nm_ip4_address_dup (NMIP4Address *source)
 {
@@ -1049,6 +1309,12 @@ nm_ip4_address_dup (NMIP4Address *source)
 	return address;
 }
 
+/**
+ * nm_ip4_address_ref:
+ * @address: the #NMIP4Address
+ *
+ * Increases the reference count of the object.
+ **/
 void
 nm_ip4_address_ref (NMIP4Address *address)
 {
@@ -1058,6 +1324,13 @@ nm_ip4_address_ref (NMIP4Address *address)
 	address->refcount++;
 }
 
+/**
+ * nm_ip4_address_unref:
+ * @address: the #NMIP4Address
+ *
+ * Decreases the reference count of the object.  If the reference count
+ * reaches zero, the object will be destroyed.
+ **/
 void
 nm_ip4_address_unref (NMIP4Address *address)
 {
@@ -1071,6 +1344,15 @@ nm_ip4_address_unref (NMIP4Address *address)
 	}
 }
 
+/**
+ * nm_ip4_address_compare:
+ * @address: the #NMIP4Address
+ * @other: the #NMIP4Address to compare @address to.
+ *
+ * Determines if two #NMIP4Address objects contain the same values.
+ *
+ * Returns: %TRUE if the objects contain the same values, %FALSE if they do not.
+ **/
 gboolean
 nm_ip4_address_compare (NMIP4Address *address, NMIP4Address *other)
 {
@@ -1087,6 +1369,14 @@ nm_ip4_address_compare (NMIP4Address *address, NMIP4Address *other)
 	return TRUE;
 }
 
+/**
+ * nm_ip4_address_get_address:
+ * @address: the #NMIP4Address
+ *
+ * Gets the IPv4 address property of this address object.
+ *
+ * Returns: the IPv4 address in network byte order
+ **/
 guint32
 nm_ip4_address_get_address (NMIP4Address *address)
 {
@@ -1096,6 +1386,13 @@ nm_ip4_address_get_address (NMIP4Address *address)
 	return address->address;
 }
 
+/**
+ * nm_ip4_address_set_address:
+ * @address: the #NMIP4Address
+ * @addr: the IPv4 address in network byte order
+ *
+ * Sets the IPv4 address property of this object.
+ **/
 void
 nm_ip4_address_set_address (NMIP4Address *address, guint32 addr)
 {
@@ -1105,6 +1402,15 @@ nm_ip4_address_set_address (NMIP4Address *address, guint32 addr)
 	address->address = addr;
 }
 
+/**
+ * nm_ip4_address_get_prefix:
+ * @address: the #NMIP4Address
+ *
+ * Gets the IPv4 address prefix (ie "24" or "30" etc) property of this address
+ * object.
+ *
+ * Returns: the IPv4 address prefix
+ **/
 guint32
 nm_ip4_address_get_prefix (NMIP4Address *address)
 {
@@ -1114,15 +1420,32 @@ nm_ip4_address_get_prefix (NMIP4Address *address)
 	return address->prefix;
 }
 
+/**
+ * nm_ip4_address_set_prefix:
+ * @address: the #NMIP4Address
+ * @prefix: the address prefix, a number between 1 and 32 inclusive
+ *
+ * Sets the IPv4 address prefix.
+ **/
 void
 nm_ip4_address_set_prefix (NMIP4Address *address, guint32 prefix)
 {
 	g_return_if_fail (address != NULL);
 	g_return_if_fail (address->refcount > 0);
+	g_return_if_fail (prefix <= 32);
+	g_return_if_fail (prefix > 0);
 
 	address->prefix = prefix;
 }
 
+/**
+ * nm_ip4_address_get_gateway:
+ * @address: the #NMIP4Address
+ *
+ * Gets the IPv4 default gateway property of this address object.
+ *
+ * Returns: the IPv4 gateway address in network byte order
+ **/
 guint32
 nm_ip4_address_get_gateway (NMIP4Address *address)
 {
@@ -1132,6 +1455,13 @@ nm_ip4_address_get_gateway (NMIP4Address *address)
 	return address->gateway;
 }
 
+/**
+ * nm_ip4_address_set_gateway:
+ * @address: the #NMIP4Address
+ * @gateway: the IPv4 default gateway in network byte order
+ *
+ * Sets the IPv4 default gateway property of this address object.
+ **/
 void
 nm_ip4_address_set_gateway (NMIP4Address *address, guint32 gateway)
 {
@@ -1151,6 +1481,13 @@ struct NMIP4Route {
 	guint32 metric;    /* lower metric == more preferred */
 };
 
+/**
+ * nm_ip4_route_new:
+ *
+ * Creates and returns a new #NMIP4Route object.
+ *
+ * Returns: (transfer full): the new empty #NMIP4Route object
+ **/
 NMIP4Route *
 nm_ip4_route_new (void)
 {
@@ -1161,6 +1498,14 @@ nm_ip4_route_new (void)
 	return route;
 }
 
+/**
+ * nm_ip4_route_dup:
+ * @source: the #NMIP4Route object to copy
+ *
+ * Copies a given #NMIP4Route object and returns the copy.
+ *
+ * Returns: (transfer full): the copy of the given #NMIP4Route copy
+ **/
 NMIP4Route *
 nm_ip4_route_dup (NMIP4Route *source)
 {
@@ -1178,6 +1523,12 @@ nm_ip4_route_dup (NMIP4Route *source)
 	return route;
 }
 
+/**
+ * nm_ip4_route_ref:
+ * @route: the #NMIP4Route
+ *
+ * Increases the reference count of the object.
+ **/
 void
 nm_ip4_route_ref (NMIP4Route *route)
 {
@@ -1187,6 +1538,13 @@ nm_ip4_route_ref (NMIP4Route *route)
 	route->refcount++;
 }
 
+/**
+ * nm_ip4_route_unref:
+ * @route: the #NMIP4Route
+ *
+ * Decreases the reference count of the object.  If the reference count
+ * reaches zero, the object will be destroyed.
+ **/
 void
 nm_ip4_route_unref (NMIP4Route *route)
 {
@@ -1200,6 +1558,15 @@ nm_ip4_route_unref (NMIP4Route *route)
 	}
 }
 
+/**
+ * nm_ip4_route_compare:
+ * @route: the #NMIP4Route
+ * @other: the #NMIP4Route to compare @route to.
+ *
+ * Determines if two #NMIP4Route objects contain the same values.
+ *
+ * Returns: %TRUE if the objects contain the same values, %FALSE if they do not.
+ **/
 gboolean
 nm_ip4_route_compare (NMIP4Route *route, NMIP4Route *other)
 {
@@ -1217,6 +1584,14 @@ nm_ip4_route_compare (NMIP4Route *route, NMIP4Route *other)
 	return TRUE;
 }
 
+/**
+ * nm_ip4_route_get_dest:
+ * @route: the #NMIP4Route
+ *
+ * Gets the IPv4 destination address property of this route object.
+ *
+ * Returns: the IPv4 address in network byte order
+ **/
 guint32
 nm_ip4_route_get_dest (NMIP4Route *route)
 {
@@ -1226,6 +1601,13 @@ nm_ip4_route_get_dest (NMIP4Route *route)
 	return route->dest;
 }
 
+/**
+ * nm_ip4_route_set_dest:
+ * @route: the #NMIP4Route
+ * @dest: the destination address in network byte order
+ *
+ * Sets the IPv4 destination address property of this route object.
+ **/
 void
 nm_ip4_route_set_dest (NMIP4Route *route, guint32 dest)
 {
@@ -1235,6 +1617,14 @@ nm_ip4_route_set_dest (NMIP4Route *route, guint32 dest)
 	route->dest = dest;
 }
 
+/**
+ * nm_ip4_route_get_prefix:
+ * @route: the #NMIP4Route
+ *
+ * Gets the IPv4 prefix (ie "24" or "30" etc) of this route.
+ *
+ * Returns: the IPv4 prefix
+ **/
 guint32
 nm_ip4_route_get_prefix (NMIP4Route *route)
 {
@@ -1244,15 +1634,32 @@ nm_ip4_route_get_prefix (NMIP4Route *route)
 	return route->prefix;
 }
 
+/**
+ * nm_ip4_route_set_prefix:
+ * @route: the #NMIP4Route
+ * @prefix: the prefix, a number between 1 and 32 inclusive
+ *
+ * Sets the IPv4 prefix of this route.
+ **/
 void
 nm_ip4_route_set_prefix (NMIP4Route *route, guint32 prefix)
 {
 	g_return_if_fail (route != NULL);
 	g_return_if_fail (route->refcount > 0);
+	g_return_if_fail (prefix <= 32);
+	g_return_if_fail (prefix > 0);
 
 	route->prefix = prefix;
 }
 
+/**
+ * nm_ip4_route_get_next_hop:
+ * @route: the #NMIP4Route
+ *
+ * Gets the IPv4 address of the next hop of this route.
+ *
+ * Returns: the IPv4 address in network byte order
+ **/
 guint32
 nm_ip4_route_get_next_hop (NMIP4Route *route)
 {
@@ -1262,6 +1669,13 @@ nm_ip4_route_get_next_hop (NMIP4Route *route)
 	return route->next_hop;
 }
 
+/**
+ * nm_ip4_route_set_next_hop:
+ * @route: the #NMIP4Route
+ * @next_hop: the IPv4 address of the next hop in network byte order
+ *
+ * Sets the IPv4 address of the next hop of this route.
+ **/
 void
 nm_ip4_route_set_next_hop (NMIP4Route *route, guint32 next_hop)
 {
@@ -1271,6 +1685,15 @@ nm_ip4_route_set_next_hop (NMIP4Route *route, guint32 next_hop)
 	route->next_hop = next_hop;
 }
 
+/**
+ * nm_ip4_route_get_metric:
+ * @route: the #NMIP4Route
+ *
+ * Gets the route metric property of this route object; lower values indicate
+ * "better" or more preferred routes.
+ *
+ * Returns: the route metric
+ **/
 guint32
 nm_ip4_route_get_metric (NMIP4Route *route)
 {
@@ -1280,6 +1703,14 @@ nm_ip4_route_get_metric (NMIP4Route *route)
 	return route->metric;
 }
 
+/**
+ * nm_ip4_route_set_metric:
+ * @route: the #NMIP4Route
+ * @metric: the route metric
+ *
+ * Sets the route metric property of this route object; lower values indicate
+ * "better" or more preferred routes.
+ **/
 void
 nm_ip4_route_set_metric (NMIP4Route *route, guint32 metric)
 {
diff --git a/libnm-util/nm-setting-ip4-config.h b/libnm-util/nm-setting-ip4-config.h
index 91cf0ea6..76dcf37a 100644
--- a/libnm-util/nm-setting-ip4-config.h
+++ b/libnm-util/nm-setting-ip4-config.h
@@ -39,8 +39,16 @@ G_BEGIN_DECLS
 
 #define NM_SETTING_IP4_CONFIG_SETTING_NAME "ipv4"
 
-typedef enum
-{
+/**
+ * NMSettingIP4ConfigError:
+ * @NM_SETTING_IP4_CONFIG_ERROR_UNKNOWN: unknown or unclassified error
+ * @NM_SETTING_IP4_CONFIG_ERROR_INVALID_PROPERTY: the property was invalid
+ * @NM_SETTING_IP4_CONFIG_ERROR_MISSING_PROPERTY: the property was missing and is
+ * required
+ * @NM_SETTING_IP4_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD: the property's value is
+ * not valid with the given IP4 method
+ */
+typedef enum {
 	NM_SETTING_IP4_CONFIG_ERROR_UNKNOWN = 0,
 	NM_SETTING_IP4_CONFIG_ERROR_INVALID_PROPERTY,
 	NM_SETTING_IP4_CONFIG_ERROR_MISSING_PROPERTY,
@@ -66,10 +74,48 @@ GQuark nm_setting_ip4_config_error_quark (void);
 #define NM_SETTING_IP4_CONFIG_NEVER_DEFAULT      "never-default"
 #define NM_SETTING_IP4_CONFIG_MAY_FAIL           "may-fail"
 
+/**
+ * NM_SETTING_IP4_CONFIG_METHOD_AUTO:
+ *
+ * IPv4 configuration should be automatically determined via a method appropriate
+ * for the hardware interface, ie DHCP or PPP or some other device-specific
+ * manner.
+ */
 #define NM_SETTING_IP4_CONFIG_METHOD_AUTO       "auto"
+
+/**
+ * NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL:
+ *
+ * IPv4 configuration should be automatically configured for link-local-only
+ * operation.
+ */
 #define NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL "link-local"
+
+/**
+ * NM_SETTING_IP4_CONFIG_METHOD_MANUAL:
+ *
+ * All necessary IPv4 configuration (addresses, prefix, DNS, etc) is specified
+ * in the setting's properties.
+ */
 #define NM_SETTING_IP4_CONFIG_METHOD_MANUAL     "manual"
+
+/**
+ * NM_SETTING_IP4_CONFIG_METHOD_SHARED:
+ *
+ * This connection specifies configuration that allows other computers to
+ * connect through it to the default network (usually the Internet).  The
+ * connection's interface will be assigned a private address, and a DHCP server,
+ * caching DNS server, and Network Address Translation (NAT) functionality will
+ * be started on this connection's interface to allow other devices to connect
+ * through that interface to the default network.
+ */
 #define NM_SETTING_IP4_CONFIG_METHOD_SHARED     "shared"
+
+/**
+ * NM_SETTING_IP4_CONFIG_METHOD_DISABLED:
+ *
+ * This connection does not use or require IPv4 address and it should be disabled.
+ */
 #define NM_SETTING_IP4_CONFIG_METHOD_DISABLED   "disabled"
 
 typedef struct NMIP4Address NMIP4Address;
@@ -100,7 +146,7 @@ typedef struct NMIP4Route NMIP4Route;
 GType nm_ip4_route_get_type (void);
 
 NMIP4Route * nm_ip4_route_new          (void);
-NMIP4Route * nm_ip4_route_dup          (NMIP4Route *route);
+NMIP4Route * nm_ip4_route_dup          (NMIP4Route *source);
 void         nm_ip4_route_ref          (NMIP4Route *route);
 void         nm_ip4_route_unref        (NMIP4Route *route);
 /* Return TRUE if routes are identical */
diff --git a/libnm-util/nm-setting-ip6-config.c b/libnm-util/nm-setting-ip6-config.c
index 1adbbdcb..4dc8f46c 100644
--- a/libnm-util/nm-setting-ip6-config.c
+++ b/libnm-util/nm-setting-ip6-config.c
@@ -30,6 +30,22 @@
 #include "nm-utils.h"
 #include "nm-dbus-glib-types.h"
 
+/**
+ * SECTION:nm-setting-ip6-config
+ * @short_description: Describes IPv6 addressing, routing, and name service properties
+ * @include: nm-setting-ip6-config.h
+ *
+ * The #NMSettingIP6Config object is a #NMSetting subclass that describes
+ * properties related to IPv6 addressing, routing, and Domain Name Service
+ **/
+
+/**
+ * nm_setting_ip6_config_error_quark:
+ *
+ * Registers an error quark for #NMSettingIP6Config if necessary.
+ *
+ * Returns: the error quark used for #NMSettingIP6Config errors.
+ **/
 GQuark
 nm_setting_ip6_config_error_quark (void)
 {
@@ -102,12 +118,25 @@ enum {
 	LAST_PROP
 };
 
+/**
+ * nm_setting_ip6_config_new:
+ *
+ * Creates a new #NMSettingIP6Config object with default values.
+ *
+ * Returns: (transfer full): the new empty #NMSettingIP6Config object
+ **/
 NMSetting *
 nm_setting_ip6_config_new (void)
 {
 	return (NMSetting *) g_object_new (NM_TYPE_SETTING_IP6_CONFIG, NULL);
 }
 
+/**
+ * nm_setting_ip6_config_get_method:
+ * @setting: the #NMSettingIP6Config
+ *
+ * Returns: the #NMSettingIP6Config:method property of the setting
+ **/
 const char *
 nm_setting_ip6_config_get_method (NMSettingIP6Config *setting)
 {
@@ -116,6 +145,12 @@ nm_setting_ip6_config_get_method (NMSettingIP6Config *setting)
 	return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->method;
 }
 
+/**
+ * nm_setting_ip6_config_get_num_dns:
+ * @setting: the #NMSettingIP6Config
+ *
+ * Returns: the number of configured DNS servers
+ **/
 guint32
 nm_setting_ip6_config_get_num_dns (NMSettingIP6Config *setting)
 {
@@ -124,6 +159,13 @@ nm_setting_ip6_config_get_num_dns (NMSettingIP6Config *setting)
 	return g_slist_length (NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->dns);
 }
 
+/**
+ * nm_setting_ip6_config_get_dns:
+ * @setting: the #NMSettingIP6Config
+ * @i: index number of the DNS server to return
+ *
+ * Returns: (transfer none): the IPv6 address of the DNS server at index @i
+ **/
 const struct in6_addr *
 nm_setting_ip6_config_get_dns (NMSettingIP6Config *setting, guint32 i)
 {
@@ -138,6 +180,16 @@ nm_setting_ip6_config_get_dns (NMSettingIP6Config *setting, guint32 i)
 	return (const struct in6_addr *) g_slist_nth_data (priv->dns, i);
 }
 
+/**
+ * nm_setting_ip6_config_add_dns:
+ * @setting: the #NMSettingIP6Config
+ * @dns: the IPv6 address of the DNS server to add
+ *
+ * Adds a new DNS server to the setting.
+ *
+ * Returns: %TRUE if the DNS server was added; %FALSE if the server was already
+ * known
+ **/
 gboolean
 nm_setting_ip6_config_add_dns (NMSettingIP6Config *setting, const struct in6_addr *addr)
 {
@@ -160,6 +212,13 @@ nm_setting_ip6_config_add_dns (NMSettingIP6Config *setting, const struct in6_add
 	return TRUE;
 }
 
+/**
+ * nm_setting_ip6_config_remove_dns:
+ * @setting: the #NMSettingIP6Config
+ * @i: index number of the DNS server to remove
+ *
+ * Removes the DNS server at index @i.
+ **/
 void
 nm_setting_ip6_config_remove_dns (NMSettingIP6Config *setting, guint32 i)
 {
@@ -176,6 +235,12 @@ nm_setting_ip6_config_remove_dns (NMSettingIP6Config *setting, guint32 i)
 	priv->dns = g_slist_delete_link (priv->dns, elt);
 }
 
+/**
+ * nm_setting_ip6_config_clear_dns:
+ * @setting: the #NMSettingIP6Config
+ *
+ * Removes all configured DNS servers.
+ **/
 void
 nm_setting_ip6_config_clear_dns (NMSettingIP6Config *setting)
 {
@@ -185,6 +250,12 @@ nm_setting_ip6_config_clear_dns (NMSettingIP6Config *setting)
 	NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->dns = NULL;
 }
 
+/**
+ * nm_setting_ip6_config_get_num_dns_searches:
+ * @setting: the #NMSettingIP6Config
+ *
+ * Returns: the number of configured DNS search domains
+ **/
 guint32
 nm_setting_ip6_config_get_num_dns_searches (NMSettingIP6Config *setting)
 {
@@ -193,6 +264,13 @@ nm_setting_ip6_config_get_num_dns_searches (NMSettingIP6Config *setting)
 	return g_slist_length (NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->dns_search);
 }
 
+/**
+ * nm_setting_ip6_config_get_dns_search:
+ * @setting: the #NMSettingIP6Config
+ * @i: index number of the DNS search domain to return
+ *
+ * Returns: the DNS search domain at index @i
+ **/
 const char *
 nm_setting_ip6_config_get_dns_search (NMSettingIP6Config *setting, guint32 i)
 {
@@ -206,6 +284,16 @@ nm_setting_ip6_config_get_dns_search (NMSettingIP6Config *setting, guint32 i)
 	return (const char *) g_slist_nth_data (priv->dns_search, i);
 }
 
+/**
+ * nm_setting_ip6_config_add_dns_search:
+ * @setting: the #NMSettingIP6Config
+ * @dns_search: the search domain to add
+ *
+ * Adds a new DNS search domain to the setting.
+ *
+ * Returns: %TRUE if the DNS search domain was added; %FALSE if the search
+ * domain was already known
+ **/
 gboolean
 nm_setting_ip6_config_add_dns_search (NMSettingIP6Config *setting,
                                       const char *dns_search)
@@ -227,6 +315,13 @@ nm_setting_ip6_config_add_dns_search (NMSettingIP6Config *setting,
 	return TRUE;
 }
 
+/**
+ * nm_setting_ip6_config_remove_dns_search:
+ * @setting: the #NMSettingIP6Config
+ * @i: index number of the DNS search domain
+ *
+ * Removes the DNS search domain at index @i.
+ **/
 void
 nm_setting_ip6_config_remove_dns_search (NMSettingIP6Config *setting, guint32 i)
 {
@@ -243,6 +338,12 @@ nm_setting_ip6_config_remove_dns_search (NMSettingIP6Config *setting, guint32 i)
 	priv->dns_search = g_slist_delete_link (priv->dns_search, elt);
 }
 
+/**
+ * nm_setting_ip6_config_clear_dns_searches:
+ * @setting: the #NMSettingIP6Config
+ *
+ * Removes all configured DNS search domains.
+ **/
 void
 nm_setting_ip6_config_clear_dns_searches (NMSettingIP6Config *setting)
 {
@@ -252,6 +353,12 @@ nm_setting_ip6_config_clear_dns_searches (NMSettingIP6Config *setting)
 	NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->dns_search = NULL;
 }
 
+/**
+ * nm_setting_ip6_config_get_num_addresses:
+ * @setting: the #NMSettingIP6Config
+ *
+ * Returns: the number of configured addresses
+ **/
 guint32
 nm_setting_ip6_config_get_num_addresses (NMSettingIP6Config *setting)
 {
@@ -260,6 +367,13 @@ nm_setting_ip6_config_get_num_addresses (NMSettingIP6Config *setting)
 	return g_slist_length (NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->addresses);
 }
 
+/**
+ * nm_setting_ip6_config_get_address:
+ * @setting: the #NMSettingIP6Config
+ * @i: index number of the address to return
+ *
+ * Returns: the address at index @i
+ **/
 NMIP6Address *
 nm_setting_ip6_config_get_address (NMSettingIP6Config *setting, guint32 i)
 {
@@ -273,6 +387,17 @@ nm_setting_ip6_config_get_address (NMSettingIP6Config *setting, guint32 i)
 	return (NMIP6Address *) g_slist_nth_data (priv->addresses, i);
 }
 
+/**
+ * nm_setting_ip6_config_add_address:
+ * @setting: the #NMSettingIP6Config
+ * @address: the new address to add
+ *
+ * Adds a new IPv6 address and associated information to the setting.  The
+ * given address is duplicated internally and is not changed by this function.
+ *
+ * Returns: %TRUE if the address was added; %FALSE if the address was already
+ * known.
+ **/
 gboolean
 nm_setting_ip6_config_add_address (NMSettingIP6Config *setting,
                                    NMIP6Address *address)
@@ -297,6 +422,13 @@ nm_setting_ip6_config_add_address (NMSettingIP6Config *setting,
 	return TRUE;
 }
 
+/**
+ * nm_setting_ip6_config_remove_address:
+ * @setting: the #NMSettingIP6Config
+ * @i: index number of the address to remove
+ *
+ * Removes the address at index @i.
+ **/
 void
 nm_setting_ip6_config_remove_address (NMSettingIP6Config *setting, guint32 i)
 {
@@ -313,6 +445,12 @@ nm_setting_ip6_config_remove_address (NMSettingIP6Config *setting, guint32 i)
 	priv->addresses = g_slist_delete_link (priv->addresses, elt);
 }
 
+/**
+ * nm_setting_ip6_config_clear_addresses:
+ * @setting: the #NMSettingIP6Config
+ *
+ * Removes all configured addresses.
+ **/
 void
 nm_setting_ip6_config_clear_addresses (NMSettingIP6Config *setting)
 {
@@ -324,6 +462,12 @@ nm_setting_ip6_config_clear_addresses (NMSettingIP6Config *setting)
 	priv->addresses = NULL;
 }
 
+/**
+ * nm_setting_ip6_config_get_num_routes:
+ * @setting: the #NMSettingIP6Config
+ *
+ * Returns: the number of configured routes
+ **/
 guint32
 nm_setting_ip6_config_get_num_routes (NMSettingIP6Config *setting)
 {
@@ -332,6 +476,13 @@ nm_setting_ip6_config_get_num_routes (NMSettingIP6Config *setting)
 	return g_slist_length (NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->routes);
 }
 
+/**
+ * nm_setting_ip6_config_get_route:
+ * @setting: the #NMSettingIP6Config
+ * @i: index number of the route to return
+ *
+ * Returns: the route at index @i
+ **/
 NMIP6Route *
 nm_setting_ip6_config_get_route (NMSettingIP6Config *setting, guint32 i)
 {
@@ -345,6 +496,16 @@ nm_setting_ip6_config_get_route (NMSettingIP6Config *setting, guint32 i)
 	return (NMIP6Route *) g_slist_nth_data (priv->routes, i);
 }
 
+/**
+ * nm_setting_ip6_config_add_route:
+ * @setting: the #NMSettingIP6Config
+ * @route: the route to add
+ *
+ * Adds a new IPv6 route and associated information to the setting.  The
+ * given route is duplicated internally and is not changed by this function.
+ *
+ * Returns: %TRUE if the route was added; %FALSE if the route was already known.
+ **/
 gboolean
 nm_setting_ip6_config_add_route (NMSettingIP6Config *setting,
                                  NMIP6Route *route)
@@ -369,6 +530,13 @@ nm_setting_ip6_config_add_route (NMSettingIP6Config *setting,
 	return TRUE;
 }
 
+/**
+ * nm_setting_ip6_config_remove_route:
+ * @setting: the #NMSettingIP6Config
+ * @i: index number of the route
+ *
+ * Removes the route at index @i.
+ **/
 void
 nm_setting_ip6_config_remove_route (NMSettingIP6Config *setting, guint32 i)
 {
@@ -385,6 +553,12 @@ nm_setting_ip6_config_remove_route (NMSettingIP6Config *setting, guint32 i)
 	priv->routes = g_slist_delete_link (priv->routes, elt);
 }
 
+/**
+ * nm_setting_ip6_config_clear_routes:
+ * @setting: the #NMSettingIP6Config
+ *
+ * Removes all configured routes.
+ **/
 void
 nm_setting_ip6_config_clear_routes (NMSettingIP6Config *setting)
 {
@@ -396,6 +570,16 @@ nm_setting_ip6_config_clear_routes (NMSettingIP6Config *setting)
 	priv->routes = NULL;
 }
 
+/**
+ * nm_setting_ip6_config_get_ignore_auto_routes:
+ * @setting: the #NMSettingIP6Config
+ *
+ * Returns the value contained in the #NMSettingIP6Config:ignore-auto-routes
+ * property.
+ *
+ * Returns: %TRUE if automatically configured (ie via DHCP) routes should be
+ * ignored.
+ **/
 gboolean
 nm_setting_ip6_config_get_ignore_auto_routes (NMSettingIP6Config *setting)
 {
@@ -404,6 +588,16 @@ nm_setting_ip6_config_get_ignore_auto_routes (NMSettingIP6Config *setting)
 	return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->ignore_auto_routes;
 }
 
+/**
+ * nm_setting_ip6_config_get_ignore_auto_dns:
+ * @setting: the #NMSettingIP6Config
+ *
+ * Returns the value contained in the #NMSettingIP6Config:ignore-auto-dns
+ * property.
+ *
+ * Returns: %TRUE if automatically configured (ie via DHCP or router
+ * advertisements) DNS information should be ignored.
+ **/
 gboolean
 nm_setting_ip6_config_get_ignore_auto_dns (NMSettingIP6Config *setting)
 {
@@ -412,6 +606,16 @@ nm_setting_ip6_config_get_ignore_auto_dns (NMSettingIP6Config *setting)
 	return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->ignore_auto_dns;
 }
 
+/**
+ * nm_setting_ip6_config_get_never_default:
+ * @setting: the #NMSettingIP6Config
+ *
+ * Returns the value contained in the #NMSettingIP6Config:never-default
+ * property.
+ *
+ * Returns: %TRUE if this connection should never be the default connection
+ * for IPv6 addressing
+ **/
 gboolean
 nm_setting_ip6_config_get_never_default (NMSettingIP6Config *setting)
 {
@@ -420,6 +624,16 @@ nm_setting_ip6_config_get_never_default (NMSettingIP6Config *setting)
 	return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->never_default;
 }
 
+/**
+ * nm_setting_ip6_config_get_may_fail:
+ * @setting: the #NMSettingIP6Config
+ *
+ * Returns the value contained in the #NMSettingIP6Config:may-fail
+ * property.
+ *
+ * Returns: %TRUE if this connection doesn't require IPv6 addressing to complete
+ * for the connection to succeed.
+ **/
 gboolean
 nm_setting_ip6_config_get_may_fail (NMSettingIP6Config *setting)
 {
@@ -842,7 +1056,7 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class)
 						   "this property to TRUE allows the overall network "
 						   "configuration to succeed if IPv6 configuration "
 						   "fails but IPv4 configuration completes successfully.",
-						   FALSE,
+						   TRUE,
 						   G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
 }
 
@@ -855,6 +1069,13 @@ struct NMIP6Address {
 	struct in6_addr gateway;
 };
 
+/**
+ * nm_ip6_address_new:
+ *
+ * Creates and returns a new #NMIP6Address object.
+ *
+ * Returns: (transfer full): the new empty #NMIP6Address object
+ **/
 NMIP6Address *
 nm_ip6_address_new (void)
 {
@@ -865,6 +1086,14 @@ nm_ip6_address_new (void)
 	return address;
 }
 
+/**
+ * nm_ip6_address_dup:
+ * @source: the #NMIP6Address object to copy
+ *
+ * Copies a given #NMIP6Address object and returns the copy.
+ *
+ * Returns: (transfer full): the copy of the given #NMIP6Address copy
+ **/
 NMIP6Address *
 nm_ip6_address_dup (NMIP6Address *source)
 {
@@ -881,6 +1110,12 @@ nm_ip6_address_dup (NMIP6Address *source)
 	return address;
 }
 
+/**
+ * nm_ip6_address_ref:
+ * @address: the #NMIP6Address
+ *
+ * Increases the reference count of the object.
+ **/
 void
 nm_ip6_address_ref (NMIP6Address *address)
 {
@@ -890,6 +1125,13 @@ nm_ip6_address_ref (NMIP6Address *address)
 	address->refcount++;
 }
 
+/**
+ * nm_ip6_address_unref:
+ * @address: the #NMIP6Address
+ *
+ * Decreases the reference count of the object.  If the reference count
+ * reaches zero, the object will be destroyed.
+ **/
 void
 nm_ip6_address_unref (NMIP6Address *address)
 {
@@ -903,6 +1145,15 @@ nm_ip6_address_unref (NMIP6Address *address)
 	}
 }
 
+/**
+ * nm_ip6_address_compare:
+ * @address: the #NMIP6Address
+ * @other: the #NMIP6Address to compare @address to.
+ *
+ * Determines if two #NMIP6Address objects contain the same values.
+ *
+ * Returns: %TRUE if the objects contain the same values, %FALSE if they do not.
+ **/
 gboolean
 nm_ip6_address_compare (NMIP6Address *address, NMIP6Address *other)
 {
@@ -919,6 +1170,14 @@ nm_ip6_address_compare (NMIP6Address *address, NMIP6Address *other)
 	return TRUE;
 }
 
+/**
+ * nm_ip6_address_get_address:
+ * @address: the #NMIP6Address
+ *
+ * Gets the IPv6 address property of this address object.
+ *
+ * Returns: (transfer none): the IPv6 address
+ **/
 const struct in6_addr *
 nm_ip6_address_get_address (NMIP6Address *address)
 {
@@ -928,6 +1187,13 @@ nm_ip6_address_get_address (NMIP6Address *address)
 	return &address->address;
 }
 
+/**
+ * nm_ip6_address_set_address:
+ * @address: the #NMIP6Address
+ * @addr: the IPv6 address
+ *
+ * Sets the IPv6 address property of this object.
+ **/
 void
 nm_ip6_address_set_address (NMIP6Address *address, const struct in6_addr *addr)
 {
@@ -938,6 +1204,14 @@ nm_ip6_address_set_address (NMIP6Address *address, const struct in6_addr *addr)
 	memcpy (&address->address, addr, sizeof (struct in6_addr));
 }
 
+/**
+ * nm_ip6_address_get_prefix:
+ * @address: the #NMIP6Address
+ *
+ * Gets the IPv6 address prefix property of this address object.
+ *
+ * Returns: the IPv6 address prefix
+ **/
 guint32
 nm_ip6_address_get_prefix (NMIP6Address *address)
 {
@@ -947,15 +1221,32 @@ nm_ip6_address_get_prefix (NMIP6Address *address)
 	return address->prefix;
 }
 
+/**
+ * nm_ip6_address_set_prefix:
+ * @address: the #NMIP6Address
+ * @prefix: the address prefix, a number between 0 and 128 inclusive
+ *
+ * Sets the IPv6 address prefix.
+ **/
 void
 nm_ip6_address_set_prefix (NMIP6Address *address, guint32 prefix)
 {
 	g_return_if_fail (address != NULL);
 	g_return_if_fail (address->refcount > 0);
+	g_return_if_fail (prefix <= 128);
+	g_return_if_fail (prefix > 0);
 
 	address->prefix = prefix;
 }
 
+/**
+ * nm_ip6_address_get_gateway:
+ * @address: the #NMIP6Address
+ *
+ * Gets the IPv6 default gateway property of this address object.
+ *
+ * Returns: (transfer none): the IPv6 gateway address
+ **/
 const struct in6_addr *
 nm_ip6_address_get_gateway (NMIP6Address *address)
 {
@@ -965,14 +1256,21 @@ nm_ip6_address_get_gateway (NMIP6Address *address)
 	return &address->gateway;
 }
 
+/**
+ * nm_ip6_address_set_gateway:
+ * @address: the #NMIP6Address
+ * @gateway: the IPv6 default gateway
+ *
+ * Sets the IPv6 default gateway property of this address object.
+ **/
 void
-nm_ip6_address_set_gateway (NMIP6Address *address, const struct in6_addr *gw)
+nm_ip6_address_set_gateway (NMIP6Address *address, const struct in6_addr *gateway)
 {
 	g_return_if_fail (address != NULL);
 	g_return_if_fail (address->refcount > 0);
-	g_return_if_fail (gw != NULL);
+	g_return_if_fail (gateway != NULL);
 
-	memcpy (&address->gateway, gw, sizeof (struct in6_addr));
+	memcpy (&address->gateway, gateway, sizeof (struct in6_addr));
 }
 
 /********************************************************************/
@@ -986,6 +1284,13 @@ struct NMIP6Route {
 	guint32 metric;    /* lower metric == more preferred */
 };
 
+/**
+ * nm_ip6_route_new:
+ *
+ * Creates and returns a new #NMIP6Route object.
+ *
+ * Returns: (transfer full): the new empty #NMIP6Route object
+ **/
 NMIP6Route *
 nm_ip6_route_new (void)
 {
@@ -996,6 +1301,14 @@ nm_ip6_route_new (void)
 	return route;
 }
 
+/**
+ * nm_ip6_route_dup:
+ * @source: the #NMIP6Route object to copy
+ *
+ * Copies a given #NMIP6Route object and returns the copy.
+ *
+ * Returns: (transfer full): the copy of the given #NMIP6Route copy
+ **/
 NMIP6Route *
 nm_ip6_route_dup (NMIP6Route *source)
 {
@@ -1013,6 +1326,12 @@ nm_ip6_route_dup (NMIP6Route *source)
 	return route;
 }
 
+/**
+ * nm_ip6_route_ref:
+ * @route: the #NMIP6Route
+ *
+ * Increases the reference count of the object.
+ **/
 void
 nm_ip6_route_ref (NMIP6Route *route)
 {
@@ -1022,6 +1341,13 @@ nm_ip6_route_ref (NMIP6Route *route)
 	route->refcount++;
 }
 
+/**
+ * nm_ip6_route_unref:
+ * @route: the #NMIP6Route
+ *
+ * Decreases the reference count of the object.  If the reference count
+ * reaches zero, the object will be destroyed.
+ **/
 void
 nm_ip6_route_unref (NMIP6Route *route)
 {
@@ -1035,6 +1361,15 @@ nm_ip6_route_unref (NMIP6Route *route)
 	}
 }
 
+/**
+ * nm_ip6_route_compare:
+ * @route: the #NMIP6Route
+ * @other: the #NMIP6Route to compare @route to.
+ *
+ * Determines if two #NMIP6Route objects contain the same values.
+ *
+ * Returns: %TRUE if the objects contain the same values, %FALSE if they do not.
+ **/
 gboolean
 nm_ip6_route_compare (NMIP6Route *route, NMIP6Route *other)
 {
@@ -1052,6 +1387,14 @@ nm_ip6_route_compare (NMIP6Route *route, NMIP6Route *other)
 	return TRUE;
 }
 
+/**
+ * nm_ip6_route_get_dest:
+ * @route: the #NMIP6Route
+ *
+ * Gets the IPv6 destination address property of this route object.
+ *
+ * Returns: the IPv6 address
+ **/
 const struct in6_addr *
 nm_ip6_route_get_dest (NMIP6Route *route)
 {
@@ -1061,6 +1404,13 @@ nm_ip6_route_get_dest (NMIP6Route *route)
 	return &route->dest;
 }
 
+/**
+ * nm_ip6_route_set_dest:
+ * @route: the #NMIP6Route
+ * @dest: the destination address
+ *
+ * Sets the IPv6 destination address property of this route object.
+ **/
 void
 nm_ip6_route_set_dest (NMIP6Route *route, const struct in6_addr *dest)
 {
@@ -1071,6 +1421,14 @@ nm_ip6_route_set_dest (NMIP6Route *route, const struct in6_addr *dest)
 	memcpy (&route->dest, dest, sizeof (struct in6_addr));
 }
 
+/**
+ * nm_ip6_route_get_prefix:
+ * @route: the #NMIP6Route
+ *
+ * Gets the IPv6 prefix (ie "32" or "64" etc) of this route.
+ *
+ * Returns: the IPv6 prefix
+ **/
 guint32
 nm_ip6_route_get_prefix (NMIP6Route *route)
 {
@@ -1080,15 +1438,32 @@ nm_ip6_route_get_prefix (NMIP6Route *route)
 	return route->prefix;
 }
 
+/**
+ * nm_ip6_route_set_prefix:
+ * @route: the #NMIP6Route
+ * @prefix: the prefix, a number between 1 and 128 inclusive
+ *
+ * Sets the IPv6 prefix of this route.
+ **/
 void
 nm_ip6_route_set_prefix (NMIP6Route *route, guint32 prefix)
 {
 	g_return_if_fail (route != NULL);
 	g_return_if_fail (route->refcount > 0);
+	g_return_if_fail (prefix <= 128);
+	g_return_if_fail (prefix > 0);
 
 	route->prefix = prefix;
 }
 
+/**
+ * nm_ip6_route_get_next_hop:
+ * @route: the #NMIP6Route
+ *
+ * Gets the IPv6 address of the next hop of this route.
+ *
+ * Returns: the IPv6 address
+ **/
 const struct in6_addr *
 nm_ip6_route_get_next_hop (NMIP6Route *route)
 {
@@ -1098,6 +1473,13 @@ nm_ip6_route_get_next_hop (NMIP6Route *route)
 	return &route->next_hop;
 }
 
+/**
+ * nm_ip6_route_set_next_hop:
+ * @route: the #NMIP6Route
+ * @next_hop: the IPv6 address of the next hop
+ *
+ * Sets the IPv6 address of the next hop of this route.
+ **/
 void
 nm_ip6_route_set_next_hop (NMIP6Route *route, const struct in6_addr *next_hop)
 {
@@ -1108,6 +1490,15 @@ nm_ip6_route_set_next_hop (NMIP6Route *route, const struct in6_addr *next_hop)
 	memcpy (&route->next_hop, next_hop, sizeof (struct in6_addr));
 }
 
+/**
+ * nm_ip6_route_get_metric:
+ * @route: the #NMIP6Route
+ *
+ * Gets the route metric property of this route object; lower values indicate
+ * "better" or more preferred routes.
+ *
+ * Returns: the route metric
+ **/
 guint32
 nm_ip6_route_get_metric (NMIP6Route *route)
 {
@@ -1117,6 +1508,14 @@ nm_ip6_route_get_metric (NMIP6Route *route)
 	return route->metric;
 }
 
+/**
+ * nm_ip6_route_set_metric:
+ * @route: the #NMIP6Route
+ * @metric: the route metric
+ *
+ * Sets the route metric property of this route object; lower values indicate
+ * "better" or more preferred routes.
+ **/
 void
 nm_ip6_route_set_metric (NMIP6Route *route, guint32 metric)
 {
diff --git a/libnm-util/nm-setting-ip6-config.h b/libnm-util/nm-setting-ip6-config.h
index b9733b4a..6b8fe5c4 100644
--- a/libnm-util/nm-setting-ip6-config.h
+++ b/libnm-util/nm-setting-ip6-config.h
@@ -40,8 +40,16 @@ G_BEGIN_DECLS
 
 #define NM_SETTING_IP6_CONFIG_SETTING_NAME "ipv6"
 
-typedef enum
-{
+/**
+ * NMSettingIP6ConfigError:
+ * @NM_SETTING_IP6_CONFIG_ERROR_UNKNOWN: unknown or unclassified error
+ * @NM_SETTING_IP6_CONFIG_ERROR_INVALID_PROPERTY: the property was invalid
+ * @NM_SETTING_IP6_CONFIG_ERROR_MISSING_PROPERTY: the property was missing and is
+ * required
+ * @NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD: the property's value is
+ * not valid with the given IPv6 method
+ */
+typedef enum {
 	NM_SETTING_IP6_CONFIG_ERROR_UNKNOWN = 0,
 	NM_SETTING_IP6_CONFIG_ERROR_INVALID_PROPERTY,
 	NM_SETTING_IP6_CONFIG_ERROR_MISSING_PROPERTY,
@@ -64,11 +72,58 @@ GQuark nm_setting_ip6_config_error_quark (void);
 #define NM_SETTING_IP6_CONFIG_NEVER_DEFAULT      "never-default"
 #define NM_SETTING_IP6_CONFIG_MAY_FAIL           "may-fail"
 
+/**
+ * NM_SETTING_IP6_CONFIG_METHOD_IGNORE:
+ *
+ * IPv6 is not required or is handled by some other mechanism, and NetworkManager
+ * should not configure IPv6 for this connection.
+ */
 #define NM_SETTING_IP6_CONFIG_METHOD_IGNORE     "ignore"
+
+/**
+ * NM_SETTING_IP6_CONFIG_METHOD_AUTO:
+ *
+ * IPv6 configuration should be automatically determined via a method appropriate
+ * for the hardware interface, ie router advertisements, DHCP, or PPP or some
+ * other device-specific manner.
+ */
 #define NM_SETTING_IP6_CONFIG_METHOD_AUTO       "auto"
+
+/**
+ * NM_SETTING_IP6_CONFIG_METHOD_DHCP:
+ *
+ * IPv6 configuration should be automatically determined via DHCPv6 only and
+ * router advertisements should be ignored.
+ */
 #define NM_SETTING_IP6_CONFIG_METHOD_DHCP       "dhcp"
+
+/**
+ * NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL:
+ *
+ * IPv6 configuration should be automatically configured for link-local-only
+ * operation.
+ */
 #define NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL "link-local"
+
+/**
+ * NM_SETTING_IP6_CONFIG_METHOD_MANUAL:
+ *
+ * All necessary IPv6 configuration (addresses, prefix, DNS, etc) is specified
+ * in the setting's properties.
+ */
 #define NM_SETTING_IP6_CONFIG_METHOD_MANUAL     "manual"
+
+/**
+ * NM_SETTING_IP6_CONFIG_METHOD_SHARED:
+ *
+ * This connection specifies configuration that allows other computers to
+ * connect through it to the default network (usually the Internet).  The
+ * connection's interface will be assigned a private address, and router
+ * advertisements, a caching DNS server, and Network Address Translation (NAT)
+ * functionality will be started on this connection's interface to allow other
+ * devices to connect through that interface to the default network. (not yet
+ * supported for IPv6)
+ */
 #define NM_SETTING_IP6_CONFIG_METHOD_SHARED     "shared"
 
 
@@ -93,14 +148,14 @@ void                   nm_ip6_address_set_prefix  (NMIP6Address *address,
 
 const struct in6_addr *nm_ip6_address_get_gateway (NMIP6Address *address);
 void                   nm_ip6_address_set_gateway (NMIP6Address *address,
-                                                   const struct in6_addr *gw);
+                                                   const struct in6_addr *gateway);
 
 typedef struct NMIP6Route NMIP6Route;
 
 GType nm_ip6_route_get_type (void);
 
 NMIP6Route *           nm_ip6_route_new          (void);
-NMIP6Route *           nm_ip6_route_dup          (NMIP6Route *route);
+NMIP6Route *           nm_ip6_route_dup          (NMIP6Route *source);
 void                   nm_ip6_route_ref          (NMIP6Route *route);
 void                   nm_ip6_route_unref        (NMIP6Route *route);
 /* Return TRUE if routes are identical */
diff --git a/libnm-util/nm-setting-ppp.c b/libnm-util/nm-setting-ppp.c
index fd6043f1..89338131 100644
--- a/libnm-util/nm-setting-ppp.c
+++ b/libnm-util/nm-setting-ppp.c
@@ -25,6 +25,24 @@
 
 #include "nm-setting-ppp.h"
 
+/**
+ * SECTION:nm-setting-ppp
+ * @short_description: Describes connection properties for devices/networks
+ * that require PPP to deliver IP capability
+ * @include: nm-setting-ppp.h
+ *
+ * The #NMSettingPPP object is a #NMSetting subclass that describes properties
+ * necessary for connection to networks that require PPP transport, like PPPoE
+ * cable and DSL modems and some mobile broadband devices.
+ **/
+
+/**
+ * nm_setting_ppp_error_quark:
+ *
+ * Registers an error quark for #NMSettingPPP if necessary.
+ *
+ * Returns: the error quark used for #NMSettingPPP errors.
+ **/
 GQuark
 nm_setting_ppp_error_quark (void)
 {
@@ -110,12 +128,25 @@ enum {
 	LAST_PROP
 };
 
+/**
+ * nm_setting_ppp_new:
+ *
+ * Creates a new #NMSettingPPP object with default values.
+ *
+ * Returns: (transfer full): the new empty #NMSettingPPP object
+ **/
 NMSetting *
 nm_setting_ppp_new (void)
 {
 	return (NMSetting *) g_object_new (NM_TYPE_SETTING_PPP, NULL);
 }
 
+/**
+ * nm_setting_wired_get_noauth:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:noauth property of the setting
+ **/
 gboolean
 nm_setting_ppp_get_noauth (NMSettingPPP *setting)
 {
@@ -124,6 +155,12 @@ nm_setting_ppp_get_noauth (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->noauth;
 }
 
+/**
+ * nm_setting_wired_get_refuse_eap:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:refuse-eap property of the setting
+ **/
 gboolean
 nm_setting_ppp_get_refuse_eap (NMSettingPPP *setting)
 {
@@ -132,6 +169,12 @@ nm_setting_ppp_get_refuse_eap (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->refuse_eap;
 }
 
+/**
+ * nm_setting_wired_get_refuse_pap:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:refuse-pap property of the setting
+ **/
 gboolean
 nm_setting_ppp_get_refuse_pap (NMSettingPPP *setting)
 {
@@ -140,6 +183,12 @@ nm_setting_ppp_get_refuse_pap (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->refuse_pap;
 }
 
+/**
+ * nm_setting_wired_get_refuse_chap:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:refuse-chap property of the setting
+ **/
 gboolean
 nm_setting_ppp_get_refuse_chap (NMSettingPPP *setting)
 {
@@ -148,6 +197,12 @@ nm_setting_ppp_get_refuse_chap (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->refuse_chap;
 }
 
+/**
+ * nm_setting_wired_get_refuse_mschap:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:refuse-mschap property of the setting
+ **/
 gboolean
 nm_setting_ppp_get_refuse_mschap (NMSettingPPP *setting)
 {
@@ -156,6 +211,12 @@ nm_setting_ppp_get_refuse_mschap (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->refuse_mschap;
 }
 
+/**
+ * nm_setting_wired_get_refuse_mschapv2:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:refuse-mschapv2 property of the setting
+ **/
 gboolean
 nm_setting_ppp_get_refuse_mschapv2 (NMSettingPPP *setting)
 {
@@ -164,6 +225,12 @@ nm_setting_ppp_get_refuse_mschapv2 (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->refuse_mschapv2;
 }
 
+/**
+ * nm_setting_wired_get_nobsdcomp:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:nobsdcomp property of the setting
+ **/
 gboolean
 nm_setting_ppp_get_nobsdcomp (NMSettingPPP *setting)
 {
@@ -172,6 +239,12 @@ nm_setting_ppp_get_nobsdcomp (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->nobsdcomp;
 }
 
+/**
+ * nm_setting_wired_get_nodeflate:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:nodeflate property of the setting
+ **/
 gboolean
 nm_setting_ppp_get_nodeflate (NMSettingPPP *setting)
 {
@@ -180,6 +253,12 @@ nm_setting_ppp_get_nodeflate (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->nodeflate;
 }
 
+/**
+ * nm_setting_wired_get_no_vj_comp:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:no-vj-comp property of the setting
+ **/
 gboolean
 nm_setting_ppp_get_no_vj_comp (NMSettingPPP *setting)
 {
@@ -188,6 +267,12 @@ nm_setting_ppp_get_no_vj_comp (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->no_vj_comp;
 }
 
+/**
+ * nm_setting_wired_get_require_mppe:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:require-mppe property of the setting
+ **/
 gboolean
 nm_setting_ppp_get_require_mppe (NMSettingPPP *setting)
 {
@@ -196,6 +281,12 @@ nm_setting_ppp_get_require_mppe (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->require_mppe;
 }
 
+/**
+ * nm_setting_wired_get_require_mppe_128:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:require-mppe-128 property of the setting
+ **/
 gboolean
 nm_setting_ppp_get_require_mppe_128 (NMSettingPPP *setting)
 {
@@ -204,6 +295,12 @@ nm_setting_ppp_get_require_mppe_128 (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->require_mppe_128;
 }
 
+/**
+ * nm_setting_wired_get_mppe_stateful:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:mppe-stateful property of the setting
+ **/
 gboolean
 nm_setting_ppp_get_mppe_stateful (NMSettingPPP *setting)
 {
@@ -212,6 +309,12 @@ nm_setting_ppp_get_mppe_stateful (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->mppe_stateful;
 }
 
+/**
+ * nm_setting_wired_get_crtscts:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:crtscts property of the setting
+ **/
 gboolean
 nm_setting_ppp_get_crtscts (NMSettingPPP *setting)
 {
@@ -220,6 +323,12 @@ nm_setting_ppp_get_crtscts (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->crtscts;
 }
 
+/**
+ * nm_setting_wired_get_baud:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:baud property of the setting
+ **/
 guint32
 nm_setting_ppp_get_baud (NMSettingPPP *setting)
 {
@@ -228,6 +337,12 @@ nm_setting_ppp_get_baud (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->baud;
 }
 
+/**
+ * nm_setting_wired_get_mru:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:mru property of the setting
+ **/
 guint32
 nm_setting_ppp_get_mru (NMSettingPPP *setting)
 {
@@ -236,6 +351,12 @@ nm_setting_ppp_get_mru (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->mru;
 }
 
+/**
+ * nm_setting_wired_get_mtu:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:mtu property of the setting
+ **/
 guint32
 nm_setting_ppp_get_mtu (NMSettingPPP *setting)
 {
@@ -244,6 +365,12 @@ nm_setting_ppp_get_mtu (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->mtu;
 }
 
+/**
+ * nm_setting_wired_get_lcp_echo_failure:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:lcp-echo-failure property of the setting
+ **/
 guint32
 nm_setting_ppp_get_lcp_echo_failure (NMSettingPPP *setting)
 {
@@ -252,6 +379,12 @@ nm_setting_ppp_get_lcp_echo_failure (NMSettingPPP *setting)
 	return NM_SETTING_PPP_GET_PRIVATE (setting)->lcp_echo_failure;
 }
 
+/**
+ * nm_setting_wired_get_lcp_echo_interval:
+ * @setting: the #NMSettingPPP
+ *
+ * Returns: the #NMSettingPPP:lcp-echo-interval property of the setting
+ **/
 guint32
 nm_setting_ppp_get_lcp_echo_interval (NMSettingPPP *setting)
 {
diff --git a/libnm-util/nm-setting-ppp.h b/libnm-util/nm-setting-ppp.h
index cfa1f57a..7a6e4e47 100644
--- a/libnm-util/nm-setting-ppp.h
+++ b/libnm-util/nm-setting-ppp.h
@@ -39,8 +39,16 @@ G_BEGIN_DECLS
 
 #define NM_SETTING_PPP_SETTING_NAME "ppp"
 
-typedef enum
-{
+/**
+ * NMSettingPPPError:
+ * @NM_SETTING_PPP_ERROR_UNKNOWN: unknown or unclassified error
+ * @NM_SETTING_PPP_ERROR_INVALID_PROPERTY: the property was invalid
+ * @NM_SETTING_PPP_ERROR_MISSING_PROPERTY: the property was missing and is
+ * required
+ * @NM_SETTING_PPP_ERROR_REQUIRE_MPPE_NOT_ALLOWED: requiring MPPE is not compatible
+ * with other setting configuration parameters
+ */
+typedef enum {
 	NM_SETTING_PPP_ERROR_UNKNOWN = 0,
 	NM_SETTING_PPP_ERROR_INVALID_PROPERTY,
 	NM_SETTING_PPP_ERROR_MISSING_PROPERTY,
diff --git a/libnm-util/nm-setting-pppoe.c b/libnm-util/nm-setting-pppoe.c
index 18dd7983..4a9b8a22 100644
--- a/libnm-util/nm-setting-pppoe.c
+++ b/libnm-util/nm-setting-pppoe.c
@@ -28,6 +28,23 @@
 #include "nm-setting-ppp.h"
 #include "nm-setting-private.h"
 
+/**
+ * SECTION:nm-setting-pppoe
+ * @short_description: Describes PPPoE connection properties
+ * @include: nm-setting-pppoe.h
+ *
+ * The #NMSettingPPPOE object is a #NMSetting subclass that describes
+ * properties necessary for connection to networks that require PPPoE connections
+ * to provide IP transport, for example cable or DSL modems.
+ **/
+
+/**
+ * nm_setting_pppoe_error_quark:
+ *
+ * Registers an error quark for #NMSettingPPPOE if necessary.
+ *
+ * Returns: the error quark used for #NMSettingPPPOE errors.
+ **/
 GQuark
 nm_setting_pppoe_error_quark (void)
 {
@@ -85,12 +102,25 @@ enum {
 	LAST_PROP
 };
 
+/**
+ * nm_setting_pppoe_new:
+ *
+ * Creates a new #NMSettingPPPOE object with default values.
+ *
+ * Returns: (transfer full): the new empty #NMSettingPPPOE object
+ **/
 NMSetting *
 nm_setting_pppoe_new (void)
 {
 	return (NMSetting *) g_object_new (NM_TYPE_SETTING_PPPOE, NULL);
 }
 
+/**
+ * nm_setting_pppoe_get_service:
+ * @setting: the #NMSettingPPPOE
+ *
+ * Returns: the #NMSettingPPPOE:service property of the setting
+ **/
 const char *
 nm_setting_pppoe_get_service  (NMSettingPPPOE *setting)
 {
@@ -99,6 +129,12 @@ nm_setting_pppoe_get_service  (NMSettingPPPOE *setting)
 	return NM_SETTING_PPPOE_GET_PRIVATE (setting)->service;
 }
 
+/**
+ * nm_setting_pppoe_get_service:
+ * @setting: the #NMSettingPPPOE
+ *
+ * Returns: the #NMSettingPPPOE:username property of the setting
+ **/
 const char *
 nm_setting_pppoe_get_username (NMSettingPPPOE *setting)
 {
@@ -107,6 +143,12 @@ nm_setting_pppoe_get_username (NMSettingPPPOE *setting)
 	return NM_SETTING_PPPOE_GET_PRIVATE (setting)->username;
 }
 
+/**
+ * nm_setting_pppoe_get_service:
+ * @setting: the #NMSettingPPPOE
+ *
+ * Returns: the #NMSettingPPPOE:password property of the setting
+ **/
 const char *
 nm_setting_pppoe_get_password (NMSettingPPPOE *setting)
 {
diff --git a/libnm-util/nm-setting-pppoe.h b/libnm-util/nm-setting-pppoe.h
index d163decb..aef6bd68 100644
--- a/libnm-util/nm-setting-pppoe.h
+++ b/libnm-util/nm-setting-pppoe.h
@@ -39,8 +39,16 @@ G_BEGIN_DECLS
 
 #define NM_SETTING_PPPOE_SETTING_NAME "pppoe"
 
-typedef enum
-{
+/**
+ * NMSettingPPPOEError:
+ * @NM_SETTING_PPPOE_ERROR_UNKNOWN: unknown or unclassified error
+ * @NM_SETTING_PPPOE_ERROR_INVALID_PROPERTY: the property was invalid
+ * @NM_SETTING_PPPOE_ERROR_MISSING_PROPERTY: the property was missing and is
+ * required
+ * @NM_SETTING_PPPOE_ERROR_MISSING_PPP_SETTING: the connection
+ * did not contain a required PPP setting for PPP related options
+ */
+typedef enum {
 	NM_SETTING_PPPOE_ERROR_UNKNOWN = 0,
 	NM_SETTING_PPPOE_ERROR_INVALID_PROPERTY,
 	NM_SETTING_PPPOE_ERROR_MISSING_PROPERTY,
diff --git a/libnm-util/nm-setting-serial.c b/libnm-util/nm-setting-serial.c
index d1d1445e..7ed15e9e 100644
--- a/libnm-util/nm-setting-serial.c
+++ b/libnm-util/nm-setting-serial.c
@@ -27,6 +27,24 @@
 
 #include "nm-setting-serial.h"
 
+/**
+ * SECTION:nm-setting-serial
+ * @short_description: Describes connection properties for devices that use
+ * serial communications
+ * @include: nm-setting-serial.h
+ *
+ * The #NMSettingSerial object is a #NMSetting subclass that describes
+ * properties necessary for connections that may use serial communications,
+ * such as mobile broadband or analog telephone connections.
+ **/
+
+/**
+ * nm_setting_serial_error_quark:
+ *
+ * Registers an error quark for #NMSettingSerial if necessary.
+ *
+ * Returns: the error quark used for #NMSettingSerial errors.
+ **/
 GQuark
 nm_setting_serial_error_quark (void)
 {
@@ -87,12 +105,25 @@ enum {
 	LAST_PROP
 };
 
+/**
+ * nm_setting_serial_new:
+ *
+ * Creates a new #NMSettingSerial object with default values.
+ *
+ * Returns: (transfer full): the new empty #NMSettingSerial object
+ **/
 NMSetting *
 nm_setting_serial_new (void)
 {
 	return (NMSetting *) g_object_new (NM_TYPE_SETTING_SERIAL, NULL);
 }
 
+/**
+ * nm_setting_serial_get_baud:
+ * @setting: the #NMSettingSerial
+ *
+ * Returns: the #NMSettingSerial:baud property of the setting
+ **/
 guint
 nm_setting_serial_get_baud (NMSettingSerial *setting)
 {
@@ -101,6 +132,12 @@ nm_setting_serial_get_baud (NMSettingSerial *setting)
 	return NM_SETTING_SERIAL_GET_PRIVATE (setting)->baud;
 }
 
+/**
+ * nm_setting_serial_get_bits:
+ * @setting: the #NMSettingSerial
+ *
+ * Returns: the #NMSettingSerial:bits property of the setting
+ **/
 guint
 nm_setting_serial_get_bits (NMSettingSerial *setting)
 {
@@ -109,6 +146,12 @@ nm_setting_serial_get_bits (NMSettingSerial *setting)
 	return NM_SETTING_SERIAL_GET_PRIVATE (setting)->bits;
 }
 
+/**
+ * nm_setting_serial_get_parity:
+ * @setting: the #NMSettingSerial
+ *
+ * Returns: the #NMSettingSerial:parity property of the setting
+ **/
 char
 nm_setting_serial_get_parity (NMSettingSerial *setting)
 {
@@ -117,6 +160,12 @@ nm_setting_serial_get_parity (NMSettingSerial *setting)
 	return NM_SETTING_SERIAL_GET_PRIVATE (setting)->parity;
 }
 
+/**
+ * nm_setting_serial_get_stopbits:
+ * @setting: the #NMSettingSerial
+ *
+ * Returns: the #NMSettingSerial:stopbits property of the setting
+ **/
 guint
 nm_setting_serial_get_stopbits (NMSettingSerial *setting)
 {
@@ -125,6 +174,12 @@ nm_setting_serial_get_stopbits (NMSettingSerial *setting)
 	return NM_SETTING_SERIAL_GET_PRIVATE (setting)->stopbits;
 }
 
+/**
+ * nm_setting_serial_get_send_delay:
+ * @setting: the #NMSettingSerial
+ *
+ * Returns: the #NMSettingSerial:send-delay property of the setting
+ **/
 guint64
 nm_setting_serial_get_send_delay (NMSettingSerial *setting)
 {
diff --git a/libnm-util/nm-setting-serial.h b/libnm-util/nm-setting-serial.h
index d39e5a79..9562950c 100644
--- a/libnm-util/nm-setting-serial.h
+++ b/libnm-util/nm-setting-serial.h
@@ -39,8 +39,16 @@ G_BEGIN_DECLS
 
 #define NM_SETTING_SERIAL_SETTING_NAME "serial"
 
-typedef enum
-{
+/**
+ * NMSettingSerialError:
+ * @NM_SETTING_SERIAL_ERROR_UNKNOWN: unknown or unclassified error
+ * @NM_SETTING_SERIAL_ERROR_INVALID_PROPERTY: the property was invalid
+ * @NM_SETTING_SERIAL_ERROR_MISSING_PROPERTY: the property was missing and is
+ * required
+ * @NM_SETTING_SERIAL_ERROR_MISSING_PPP_SETTING: one of the properties of the
+ * setting requires the connection to contain an #NMSettingPPP setting
+ */
+typedef enum {
 	NM_SETTING_SERIAL_ERROR_UNKNOWN = 0,
 	NM_SETTING_SERIAL_ERROR_INVALID_PROPERTY,
 	NM_SETTING_SERIAL_ERROR_MISSING_PROPERTY,
diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c
index 23f07383..50091cb9 100644
--- a/libnm-util/nm-setting-vpn.c
+++ b/libnm-util/nm-setting-vpn.c
@@ -32,6 +32,27 @@
 #include "nm-dbus-glib-types.h"
 #include "nm-setting-private.h"
 
+/**
+ * SECTION:nm-setting-vpn
+ * @short_description: Describes connection properties for Virtual Private Networks
+ * @include: nm-setting-vpn.h
+ *
+ * The #NMSettingVPN object is a #NMSetting subclass that describes properties
+ * necessary for connection to Virtual Private Networks.  NetworkManager uses
+ * a plugin architecture to allow easier use of new VPN types, and this
+ * setting abstracts the configuration for those plugins.  Since the configuration
+ * options are only known to the VPN plugins themselves, the VPN configuration
+ * options are stored as key/value pairs of strings rather than GObject
+ * properties.
+ **/
+
+/**
+ * nm_setting_vpn_error_quark:
+ *
+ * Registers an error quark for #NMSettingVPN if necessary.
+ *
+ * Returns: the error quark used for #NMSettingVPN errors.
+ **/
 GQuark
 nm_setting_vpn_error_quark (void)
 {
@@ -108,12 +129,28 @@ enum {
 	LAST_PROP
 };
 
+/**
+ * nm_setting_vpn_new:
+ *
+ * Creates a new #NMSettingVPN object with default values.
+ *
+ * Returns: (transfer full): the new empty #NMSettingVPN object
+ **/
 NMSetting *
 nm_setting_vpn_new (void)
 {
 	return (NMSetting *) g_object_new (NM_TYPE_SETTING_VPN, NULL);
 }
 
+/**
+ * nm_setting_vpn_get_service_type:
+ * @setting: the #NMSettingVPN
+ *
+ * Returns the service name of the VPN, which identifies the specific VPN
+ * plugin that should be used to connect to this VPN.
+ *
+ * Returns: the VPN plugin's service name
+ **/
 const char *
 nm_setting_vpn_get_service_type (NMSettingVPN *setting)
 {
@@ -122,6 +159,12 @@ nm_setting_vpn_get_service_type (NMSettingVPN *setting)
 	return NM_SETTING_VPN_GET_PRIVATE (setting)->service_type;
 }
 
+/**
+ * nm_setting_vpn_get_user_name:
+ * @setting: the #NMSettingVPN
+ *
+ * Returns: the #NMSettingVPN:user-name property of the setting
+ **/
 const char *
 nm_setting_vpn_get_user_name (NMSettingVPN *setting)
 {
@@ -130,6 +173,16 @@ nm_setting_vpn_get_user_name (NMSettingVPN *setting)
 	return NM_SETTING_VPN_GET_PRIVATE (setting)->user_name;
 }
 
+/**
+ * nm_setting_vpn_add_data_item:
+ * @setting: the #NMSettingVPN
+ * @key: a name that uniquely identifies the given value @item
+ * @item: the value to be referenced by @key
+ *
+ * Establishes a relationship between @key and @item internally in the
+ * setting which may be retrieved later.  Should not be used to store passwords
+ * or other secrets, which is what nm_setting_vpn_add_secret() is for.
+ **/
 void
 nm_setting_vpn_add_data_item (NMSettingVPN *setting,
                               const char *key,
@@ -145,6 +198,16 @@ nm_setting_vpn_add_data_item (NMSettingVPN *setting,
 	                     g_strdup (key), g_strdup (item));
 }
 
+/**
+ * nm_setting_vpn_get_data_item:
+ * @setting: the #NMSettingVPN
+ * @key: the name of the data item to retrieve
+ *
+ * Retrieves the data item of a key/value relationship previously established
+ * by nm_setting_vpn_add_data_item().
+ *
+ * Returns: the data item, if any
+ **/
 const char *
 nm_setting_vpn_get_data_item (NMSettingVPN *setting, const char *key)
 {
@@ -153,6 +216,14 @@ nm_setting_vpn_get_data_item (NMSettingVPN *setting, const char *key)
 	return (const char *) g_hash_table_lookup (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key);
 }
 
+/**
+ * nm_setting_vpn_remove_data_item:
+ * @setting: the #NMSettingVPN
+ * @key: the name of the data item to remove
+ *
+ * Deletes a key/value relationship previously established by
+ * nm_setting_vpn_add_data_item().
+ **/
 void
 nm_setting_vpn_remove_data_item (NMSettingVPN *setting, const char *key)
 {
@@ -212,6 +283,15 @@ nm_setting_vpn_foreach_data_item (NMSettingVPN *setting,
 	foreach_item_helper (NM_SETTING_VPN_GET_PRIVATE (setting)->data, func, user_data);
 }
 
+/**
+ * nm_setting_vpn_add_secret:
+ * @setting: the #NMSettingVPN
+ * @key: a name that uniquely identifies the given secret @secret
+ * @secret: the secret to be referenced by @key
+ *
+ * Establishes a relationship between @key and @secret internally in the
+ * setting which may be retrieved later.
+ **/
 void
 nm_setting_vpn_add_secret (NMSettingVPN *setting,
                            const char *key,
@@ -227,6 +307,16 @@ nm_setting_vpn_add_secret (NMSettingVPN *setting,
 	                     g_strdup (key), g_strdup (secret));
 }
 
+/**
+ * nm_setting_vpn_get_secret:
+ * @setting: the #NMSettingVPN
+ * @key: the name of the secret to retrieve
+ *
+ * Retrieves the secret of a key/value relationship previously established
+ * by nm_setting_vpn_add_secret().
+ *
+ * Returns: the secret, if any
+ **/
 const char *
 nm_setting_vpn_get_secret (NMSettingVPN *setting, const char *key)
 {
@@ -235,6 +325,14 @@ nm_setting_vpn_get_secret (NMSettingVPN *setting, const char *key)
 	return (const char *) g_hash_table_lookup (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, key);
 }
 
+/**
+ * nm_setting_vpn_remove_secret:
+ * @setting: the #NMSettingVPN
+ * @key: the name of the secret to remove
+ *
+ * Deletes a key/value relationship previously established by
+ * nm_setting_vpn_add_secret().
+ **/
 void
 nm_setting_vpn_remove_secret (NMSettingVPN *setting, const char *key)
 {
@@ -451,6 +549,68 @@ need_secrets (NMSetting *setting)
 	return g_ptr_array_sized_new (1);
 }
 
+static gboolean
+compare_one_secret (NMSettingVPN *a,
+                    NMSettingVPN *b,
+                    NMSettingCompareFlags flags)
+{
+	GHashTable *a_secrets, *b_secrets;
+	GHashTableIter iter;
+	const char *key, *val;
+
+	a_secrets = NM_SETTING_VPN_GET_PRIVATE (a)->secrets;
+	b_secrets = NM_SETTING_VPN_GET_PRIVATE (b)->secrets;
+
+	g_hash_table_iter_init (&iter, a_secrets);
+	while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &val)) {
+		NMSettingSecretFlags a_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+		NMSettingSecretFlags b_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+
+		nm_setting_get_secret_flags (NM_SETTING (a), key, &a_secret_flags, NULL);
+		nm_setting_get_secret_flags (NM_SETTING (b), key, &b_secret_flags, NULL);
+
+		/* If the secret flags aren't the same, the settings aren't the same */
+		if (a_secret_flags != b_secret_flags)
+			return FALSE;
+
+		if (   (flags & NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS)
+		    && (a_secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED))
+			continue;
+
+		if (   (flags & NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)
+		    && (a_secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED))
+			continue;
+
+		/* Now compare the values themselves */
+		if (g_strcmp0 (val, nm_setting_vpn_get_secret (b, key)) != 0)
+			return FALSE;
+	}
+
+	return TRUE;
+}
+
+static gboolean
+compare_property (NMSetting *setting,
+                  NMSetting *other,
+                  const GParamSpec *prop_spec,
+                  NMSettingCompareFlags flags)
+{
+	gboolean same;
+
+	/* We only need to treat the 'secrets' property specially */
+	if (g_strcmp0 (prop_spec->name, NM_SETTING_VPN_SECRETS) != 0)
+		return NM_SETTING_CLASS (nm_setting_vpn_parent_class)->compare_property (setting, other, prop_spec, flags);
+
+	/* Compare A to B to ensure everything in A is found in B */
+	same = compare_one_secret (NM_SETTING_VPN (setting), NM_SETTING_VPN (other), flags);
+	if (same) {
+		/* And then B to A to ensure everything in B is also found in A */
+		same = compare_one_secret (NM_SETTING_VPN (other), NM_SETTING_VPN (setting), flags);
+	}
+
+	return same;
+}
+
 static void
 destroy_one_secret (gpointer data)
 {
@@ -572,6 +732,7 @@ nm_setting_vpn_class_init (NMSettingVPNClass *setting_class)
 	parent_class->get_secret_flags  = get_secret_flags;
 	parent_class->set_secret_flags  = set_secret_flags;
 	parent_class->need_secrets      = need_secrets;
+	parent_class->compare_property  = compare_property;
 
 	/* Properties */
 	/**
@@ -595,23 +756,27 @@ nm_setting_vpn_class_init (NMSettingVPNClass *setting_class)
 	/**
 	 * NMSettinVPN:user-name:
 	 *
-	 * User name of the currently logged in user for connections provided by the
-	 * user settings service.  This name is provided to the VPN plugin to use in
-	 * lieu of a custom username provided by that VPN plugins specific
-	 * configuration.  The VPN plugin itself decides which user name to use.
+	 * If the VPN connection requires a user name for authentication, that name
+	 * should be provided here.  If the connection is available to more than
+	 * one user, and the VPN requires each user to supply a different name, then
+	 * leave this property empty.  If this property is empty, NetworkManager
+	 * will automatically supply the username of the user which requested the
+	 * VPN connection.
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_USER_NAME,
 		 g_param_spec_string (NM_SETTING_VPN_USER_NAME,
-						  "User name",
-						  "User name of the currently logged in user for "
-						  "connections provided by the user settings service.  "
-						  "This name is provided to the VPN plugin to use in "
-						  "lieu of a custom username provided by that VPN "
-						  "plugins specific configuration.  The VPN plugin "
-						  "itself decides which user name to use.",
-						  NULL,
-						  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+		                      "User name",
+		                      "If the VPN connection requires a user name for "
+		                      "authentication, that name should be provided here.  "
+		                      "If the connection is available to more than one "
+		                      "user, and the VPN requires each user to supply a "
+		                      "different name, then leave this property empty.  If "
+		                      "this property is empty, NetworkManager will "
+		                      "automatically supply the username of the user which "
+		                      "requested the VPN connection.",
+		                      NULL,
+		                      G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
 
 	/**
 	 * NMSettingVPN:data:
diff --git a/libnm-util/nm-setting-vpn.h b/libnm-util/nm-setting-vpn.h
index 6ff19286..94fd650f 100644
--- a/libnm-util/nm-setting-vpn.h
+++ b/libnm-util/nm-setting-vpn.h
@@ -39,8 +39,14 @@ G_BEGIN_DECLS
 
 #define NM_SETTING_VPN_SETTING_NAME "vpn"
 
-typedef enum
-{
+/**
+ * NMSettingVpnError:
+ * @NM_SETTING_VPN_ERROR_UNKNOWN: unknown or unclassified error
+ * @NM_SETTING_VPN_ERROR_INVALID_PROPERTY: the property was invalid
+ * @NM_SETTING_VPN_ERROR_MISSING_PROPERTY: the property was missing and is
+ * required
+ */
+typedef enum {
 	NM_SETTING_VPN_ERROR_UNKNOWN = 0,
 	NM_SETTING_VPN_ERROR_INVALID_PROPERTY,
 	NM_SETTING_VPN_ERROR_MISSING_PROPERTY,
@@ -71,6 +77,13 @@ typedef struct {
 	void (*_reserved4) (void);
 } NMSettingVPNClass;
 
+/**
+ * NMVPNIterFunc:
+ * @key: the name of the data or secret item
+ * @value: the value of the data or secret item
+ * @user_data: User data passed to nm_setting_vpn_foreach_data_item() or
+ * nm_setting_vpn_foreach_secret()
+ **/
 typedef void (*NMVPNIterFunc) (const char *key, const char *value, gpointer user_data);
 
 GType nm_setting_vpn_get_type (void);
diff --git a/libnm-util/nm-setting-wimax.c b/libnm-util/nm-setting-wimax.c
index 628c81d3..38a442f6 100644
--- a/libnm-util/nm-setting-wimax.c
+++ b/libnm-util/nm-setting-wimax.c
@@ -27,6 +27,22 @@
 #include "nm-setting-wimax.h"
 #include "nm-param-spec-specialized.h"
 
+/**
+ * SECTION:nm-setting-wimax
+ * @short_description: Describes 802.16e Mobile WiMAX connection properties
+ * @include: nm-setting-wimax.h
+ *
+ * The #NMSettingWimax object is a #NMSetting subclass that describes properties
+ * necessary for connection to 802.16e Mobile WiMAX networks.
+ **/
+
+/**
+ * nm_setting_wimax_error_quark:
+ *
+ * Registers an error quark for #NMSettingWimax if necessary.
+ *
+ * Returns: the error quark used for #NMSettingWimax errors.
+ **/
 GQuark
 nm_setting_wimax_error_quark (void)
 {
@@ -78,12 +94,28 @@ enum {
 	LAST_PROP
 };
 
+/**
+ * nm_setting_wimax_new:
+ *
+ * Creates a new #NMSettingWimax object with default values.
+ *
+ * Returns: the new empty #NMSettingWimax object
+ **/
 NMSetting *
 nm_setting_wimax_new (void)
 {
 	return (NMSetting *) g_object_new (NM_TYPE_SETTING_WIMAX, NULL);
 }
 
+/**
+ * nm_setting_wimax_get_network_name:
+ * @setting: the #NMSettingWimax
+ *
+ * Returns the WiMAX NSP name (ex "Sprint" or "CLEAR") which identifies the
+ * specific WiMAX network this setting describes a connection to.
+ *
+ * Returns: the WiMAX NSP name
+ **/
 const char *
 nm_setting_wimax_get_network_name (NMSettingWimax *setting)
 {
@@ -92,6 +124,15 @@ nm_setting_wimax_get_network_name (NMSettingWimax *setting)
 	return NM_SETTING_WIMAX_GET_PRIVATE (setting)->network_name;
 }
 
+/**
+ * nm_setting_wimax_get_mac_address:
+ * @setting: the #NMSettingWimax
+ *
+ * Returns the MAC address of a WiMAX device which this connection is locked
+ * to.
+ *
+ * Returns: the MAC address
+ **/
 const GByteArray *
 nm_setting_wimax_get_mac_address (NMSettingWimax *setting)
 {
diff --git a/libnm-util/nm-setting-wimax.h b/libnm-util/nm-setting-wimax.h
index a3e500be..2462ac06 100644
--- a/libnm-util/nm-setting-wimax.h
+++ b/libnm-util/nm-setting-wimax.h
@@ -35,8 +35,14 @@ G_BEGIN_DECLS
 
 #define NM_SETTING_WIMAX_SETTING_NAME "wimax"
 
-typedef enum
-{
+/**
+ * NMSettingWimaxError:
+ * @NM_SETTING_WIMAX_ERROR_UNKNOWN: unknown or unclassified error
+ * @NM_SETTING_WIMAX_ERROR_INVALID_PROPERTY: the property was invalid
+ * @NM_SETTING_WIMAX_ERROR_MISSING_PROPERTY: the property was missing and is
+ * required
+ */
+typedef enum {
 	NM_SETTING_WIMAX_ERROR_UNKNOWN = 0,
 	NM_SETTING_WIMAX_ERROR_INVALID_PROPERTY,
 	NM_SETTING_WIMAX_ERROR_MISSING_PROPERTY
diff --git a/libnm-util/nm-setting-wired.c b/libnm-util/nm-setting-wired.c
index 8691aeee..d4e52e03 100644
--- a/libnm-util/nm-setting-wired.c
+++ b/libnm-util/nm-setting-wired.c
@@ -19,7 +19,7 @@
  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301 USA.
  *
- * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ * (C) Copyright 2007 - 2011 Red Hat, Inc.
  * (C) Copyright 2007 - 2008 Novell, Inc.
  */
 
@@ -27,6 +27,7 @@
 #include <ctype.h>
 #include <net/ethernet.h>
 #include <dbus/dbus-glib.h>
+#include <netinet/ether.h>
 
 #include "nm-setting-wired.h"
 #include "nm-param-spec-specialized.h"
@@ -34,6 +35,22 @@
 #include "nm-utils-private.h"
 #include "nm-dbus-glib-types.h"
 
+/**
+ * SECTION:nm-setting-wired
+ * @short_description: Describes connection properties for Ethernet-based networks
+ * @include: nm-setting-wired.h
+ *
+ * The #NMSettingWired object is a #NMSetting subclass that describes properties
+ * necessary for connection to Ethernet networks.
+ **/
+
+/**
+ * nm_setting_wired_error_quark:
+ *
+ * Registers an error quark for #NMSettingWired if necessary.
+ *
+ * Returns: the error quark used for #NMSettingWired errors.
+ **/
 GQuark
 nm_setting_wired_error_quark (void)
 {
@@ -79,6 +96,7 @@ typedef struct {
 	gboolean auto_negotiate;
 	GByteArray *device_mac_address;
 	GByteArray *cloned_mac_address;
+	GSList *mac_address_blacklist;
 	guint32 mtu;
 	GPtrArray *s390_subchannels;
 	char *s390_nettype;
@@ -93,6 +111,7 @@ enum {
 	PROP_AUTO_NEGOTIATE,
 	PROP_MAC_ADDRESS,
 	PROP_CLONED_MAC_ADDRESS,
+	PROP_MAC_ADDRESS_BLACKLIST,
 	PROP_MTU,
 	PROP_S390_SUBCHANNELS,
 	PROP_S390_NETTYPE,
@@ -111,12 +130,25 @@ static const char *valid_s390_opts[] = {
 	NULL
 };
 
+/**
+ * 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 (NMSetting *) g_object_new (NM_TYPE_SETTING_WIRED, NULL);
 }
 
+/**
+ * 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)
 {
@@ -125,6 +157,12 @@ nm_setting_wired_get_port (NMSettingWired *setting)
 	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)
 {
@@ -133,6 +171,12 @@ nm_setting_wired_get_speed (NMSettingWired *setting)
 	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)
 {
@@ -141,6 +185,12 @@ nm_setting_wired_get_duplex (NMSettingWired *setting)
 	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)
 {
@@ -149,6 +199,12 @@ nm_setting_wired_get_auto_negotiate (NMSettingWired *setting)
 	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 GByteArray *
 nm_setting_wired_get_mac_address (NMSettingWired *setting)
 {
@@ -157,6 +213,12 @@ nm_setting_wired_get_mac_address (NMSettingWired *setting)
 	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 GByteArray *
 nm_setting_wired_get_cloned_mac_address (NMSettingWired *setting)
 {
@@ -165,6 +227,27 @@ nm_setting_wired_get_cloned_mac_address (NMSettingWired *setting)
 	return NM_SETTING_WIRED_GET_PRIVATE (setting)->cloned_mac_address;
 }
 
+/**
+ * nm_setting_wired_get_mac_address_blacklist:
+ * @setting: the #NMSettingWired
+ *
+ * Returns: (element-type GLib.ByteArray): the #NMSettingWired:mac-address-blacklist
+ * property of the setting
+ **/
+const GSList *
+nm_setting_wired_get_mac_address_blacklist (NMSettingWired *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL);
+
+	return NM_SETTING_WIRED_GET_PRIVATE (setting)->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)
 {
@@ -181,8 +264,8 @@ nm_setting_wired_get_mtu (NMSettingWired *setting)
  * connection is applicable to.  The connection should only be used in
  * conjunction with that device.
  *
- * Returns: a #GPtrArray of strings, each specifying one subchannel the
- * s390 device uses to communicate to the host.
+ * Returns: (element-type utf8): #GPtrArray of strings, each specifying one
+ * subchannel the s390 device uses to communicate to the host.
  **/
 const GPtrArray *
 nm_setting_wired_get_s390_subchannels (NMSettingWired *setting)
@@ -232,10 +315,10 @@ nm_setting_wired_get_num_s390_options (NMSettingWired *setting)
  * @setting: the #NMSettingWired
  * @idx: index of the desired option, from 0 to
  * nm_setting_wired_get_num_s390_options() - 1
- * @out_key: on return, the key name of the s390 specific option; this value is
- * owned by the setting and should not be modified
- * @out_value: on return, the value of the key of the s390 specific option; this
+ * @out_key: (out): 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): 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
@@ -363,6 +446,7 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
 	const char *valid_duplex[] = { "half", "full", NULL };
 	const char *valid_nettype[] = { "qeth", "lcs", "ctc", NULL };
 	GHashTableIter iter;
+	GSList* mac_blacklist_iter;
 	const char *key, *value;
 
 	if (priv->port && !_nm_utils_string_in_list (priv->port, valid_ports)) {
@@ -389,6 +473,19 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
 		return FALSE;
 	}
 
+	for (mac_blacklist_iter = priv->mac_address_blacklist; mac_blacklist_iter;
+	     mac_blacklist_iter = mac_blacklist_iter->next) {
+		struct ether_addr addr;
+
+		if (!ether_aton_r (mac_blacklist_iter->data, &addr)) {
+			g_set_error (error,
+			             NM_SETTING_WIRED_ERROR,
+			             NM_SETTING_WIRED_ERROR_INVALID_PROPERTY,
+			             NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST);
+			return FALSE;
+		}
+	}
+
 	if (   priv->s390_subchannels
 	    && !(priv->s390_subchannels->len == 3 || priv->s390_subchannels->len == 2)) {
 		g_set_error (error,
@@ -456,6 +553,8 @@ finalize (GObject *object)
 	if (priv->cloned_mac_address)
 		g_byte_array_free (priv->cloned_mac_address, TRUE);
 
+	nm_utils_slist_free (priv->mac_address_blacklist, g_free);
+
 	G_OBJECT_CLASS (nm_setting_wired_parent_class)->finalize (object);
 }
 
@@ -497,6 +596,10 @@ set_property (GObject *object, guint prop_id,
 			g_byte_array_free (priv->cloned_mac_address, TRUE);
 		priv->cloned_mac_address = g_value_dup_boxed (value);
 		break;
+	case PROP_MAC_ADDRESS_BLACKLIST:
+		nm_utils_slist_free (priv->mac_address_blacklist, g_free);
+		priv->mac_address_blacklist = g_value_dup_boxed (value);
+		break;
 	case PROP_MTU:
 		priv->mtu = g_value_get_uint (value);
 		break;
@@ -550,6 +653,9 @@ get_property (GObject *object, guint prop_id,
 	case PROP_CLONED_MAC_ADDRESS:
 		g_value_set_boxed (value, nm_setting_wired_get_cloned_mac_address (setting));
 		break;
+	case PROP_MAC_ADDRESS_BLACKLIST:
+		g_value_set_boxed (value, nm_setting_wired_get_mac_address_blacklist (setting));
+		break;
 	case PROP_MTU:
 		g_value_set_uint (value, nm_setting_wired_get_mtu (setting));
 		break;
@@ -685,6 +791,25 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class)
 	                                     "This is known as MAC cloning or spoofing.",
 	                                     DBUS_TYPE_G_UCHAR_ARRAY,
 	                                     G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+    
+	/**
+	 * 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).
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_MAC_ADDRESS_BLACKLIST,
+		 _nm_param_spec_specialized (NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST,
+		                             "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).",
+		                             DBUS_TYPE_G_LIST_OF_STRING,
+		                             G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE));
 
 	/**
 	 * NMSettingWired:mtu:
diff --git a/libnm-util/nm-setting-wired.h b/libnm-util/nm-setting-wired.h
index 32361b4b..36799fbe 100644
--- a/libnm-util/nm-setting-wired.h
+++ b/libnm-util/nm-setting-wired.h
@@ -19,7 +19,7 @@
  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301 USA.
  *
- * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ * (C) Copyright 2007 - 2011 Red Hat, Inc.
  * (C) Copyright 2007 - 2008 Novell, Inc.
  */
 
@@ -39,8 +39,14 @@ G_BEGIN_DECLS
 
 #define NM_SETTING_WIRED_SETTING_NAME "802-3-ethernet"
 
-typedef enum
-{
+/**
+ * NMSettingWiredError:
+ * @NM_SETTING_WIRED_ERROR_UNKNOWN: unknown or unclassified error
+ * @NM_SETTING_WIRED_ERROR_INVALID_PROPERTY: the property was invalid
+ * @NM_SETTING_WIRED_ERROR_MISSING_PROPERTY: the property was missing and is
+ * required
+ */
+typedef enum {
 	NM_SETTING_WIRED_ERROR_UNKNOWN = 0,
 	NM_SETTING_WIRED_ERROR_INVALID_PROPERTY,
 	NM_SETTING_WIRED_ERROR_MISSING_PROPERTY
@@ -58,6 +64,7 @@ GQuark nm_setting_wired_error_quark (void);
 #define NM_SETTING_WIRED_AUTO_NEGOTIATE "auto-negotiate"
 #define NM_SETTING_WIRED_MAC_ADDRESS "mac-address"
 #define NM_SETTING_WIRED_CLONED_MAC_ADDRESS "cloned-mac-address"
+#define NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST "mac-address-blacklist"
 #define NM_SETTING_WIRED_MTU "mtu"
 #define NM_SETTING_WIRED_S390_SUBCHANNELS "s390-subchannels"
 #define NM_SETTING_WIRED_S390_NETTYPE "s390-nettype"
@@ -86,6 +93,7 @@ const char *      nm_setting_wired_get_duplex           (NMSettingWired *setting
 gboolean          nm_setting_wired_get_auto_negotiate   (NMSettingWired *setting);
 const GByteArray *nm_setting_wired_get_mac_address      (NMSettingWired *setting);
 const GByteArray *nm_setting_wired_get_cloned_mac_address (NMSettingWired *setting);
+const GSList     *nm_setting_wired_get_mac_address_blacklist (NMSettingWired *setting);
 guint32           nm_setting_wired_get_mtu              (NMSettingWired *setting);
 
 const GPtrArray * nm_setting_wired_get_s390_subchannels (NMSettingWired *setting);
diff --git a/libnm-util/nm-setting-wireless-security.c b/libnm-util/nm-setting-wireless-security.c
index 3b4eba6f..cb9a6081 100644
--- a/libnm-util/nm-setting-wireless-security.c
+++ b/libnm-util/nm-setting-wireless-security.c
@@ -35,6 +35,36 @@
 #include "nm-utils-private.h"
 #include "nm-setting-private.h"
 
+/**
+ * SECTION:nm-setting-wireless-security
+ * @short_description: Describes connection properties for WiFi networks that
+ * use WEP, LEAP, WPA or WPA2/RSN security
+ * @include: nm-setting-wireless-security.h
+ *
+ * The #NMSettingWirelessSecurity object is a #NMSetting subclass that describes
+ * properties necessary for connection to encrypted WiFi networks.
+ *
+ * It's a good idea to read up on wpa_supplicant configuration before using this
+ * setting extensively, since most of the options here correspond closely with
+ * the relevant wpa_supplicant configuration options.  To get a better overview
+ * of how WiFi security works, you may want to get copies of the following books.
+ *
+ *  802.11 Wireless Networks: The Definitive Guide, Second Edition
+ *       Author: Matthew Gast
+ *       ISBN: 978-0596100520
+ *
+ *  Cisco Wireless LAN Security
+ *       Authors: Krishna Sankar, Sri Sundaralingam, Darrin Miller, and Andrew Balinsky
+ *       ISBN: 978-1587051548
+ **/
+
+/**
+ * nm_setting_wired_error_quark:
+ *
+ * Registers an error quark for #NMSettingWired if necessary.
+ *
+ * Returns: the error quark used for #NMSettingWired errors.
+ **/
 GQuark
 nm_setting_wireless_security_error_quark (void)
 {
@@ -130,12 +160,25 @@ enum {
 	LAST_PROP
 };
 
+/**
+ * nm_setting_wireless_security_new:
+ *
+ * Creates a new #NMSettingWirelessSecurity object with default values.
+ *
+ * Returns: (transfer full): the new empty #NMSettingWirelessSecurity object
+ **/
 NMSetting *
 nm_setting_wireless_security_new (void)
 {
 	return (NMSetting *) g_object_new (NM_TYPE_SETTING_WIRELESS_SECURITY, NULL);
 }
 
+/**
+ * nm_setting_wireless_security_get_key_mgmt:
+ * @setting: the #NMSettingWirelessSecurity
+ *
+ * Returns: the #NMSettingWirelessSecurity:key-mgmt property of the setting
+ **/
 const char *
 nm_setting_wireless_security_get_key_mgmt (NMSettingWirelessSecurity *setting)
 {
@@ -144,6 +187,13 @@ nm_setting_wireless_security_get_key_mgmt (NMSettingWirelessSecurity *setting)
 	return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->key_mgmt;
 }
 
+/**
+ * nm_setting_wireless_security_get_num_protos:
+ * @setting: the #NMSettingWirelessSecurity
+ *
+ * Returns: the number of security protocols this connection allows when
+ * connecting to secure WiFi networks
+ **/
 guint32
 nm_setting_wireless_security_get_num_protos (NMSettingWirelessSecurity *setting)
 {
@@ -152,6 +202,13 @@ nm_setting_wireless_security_get_num_protos (NMSettingWirelessSecurity *setting)
 	return g_slist_length (NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->proto);
 }
 
+/**
+ * nm_setting_wireless_security_get_proto:
+ * @setting: the #NMSettingWirelessSecurity
+ * @i: an index into the protocol list
+ *
+ * Returns: the protocol at index @i
+ **/
 const char *
 nm_setting_wireless_security_get_proto (NMSettingWirelessSecurity *setting, guint32 i)
 {
@@ -165,6 +222,21 @@ nm_setting_wireless_security_get_proto (NMSettingWirelessSecurity *setting, guin
 	return (const char *) g_slist_nth_data (priv->proto, i);
 }
 
+/**
+ * nm_setting_wireless_security_add_proto:
+ * @setting: the #NMSettingWirelessSecurity
+ * @proto: the protocol to add, one of "wpa" or "rsn"
+ *
+ * Adds a WiFi security protocol (one of "wpa" or "rsn") to the allowed list;
+ * only protocols in this list will be used when finding and connecting to
+ * the WiFi network specified by this connection.  For example, if the
+ * protocol list contains only "wpa" but the access point for the SSID specified
+ * by this connection only supports WPA2/RSN, the connection cannot be used
+ * with the access point.
+ *
+ * Returns: %TRUE if the protocol was new and and was added to the allowed
+ * protocol list, or %FALSE if it was already in the list
+ **/
 gboolean
 nm_setting_wireless_security_add_proto (NMSettingWirelessSecurity *setting, const char *proto)
 {
@@ -176,7 +248,7 @@ nm_setting_wireless_security_add_proto (NMSettingWirelessSecurity *setting, cons
 
 	priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
 	for (iter = priv->proto; iter; iter = g_slist_next (iter)) {
-		if (!strcmp (proto, (char *) iter->data))
+		if (strcasecmp (proto, (char *) iter->data) == 0)
 			return FALSE;
 	}
 
@@ -184,6 +256,13 @@ nm_setting_wireless_security_add_proto (NMSettingWirelessSecurity *setting, cons
 	return TRUE;
 }
 
+/**
+ * nm_setting_wireless_security_remove_proto:
+ * @setting: the #NMSettingWirelessSecurity
+ * @i: index of the protocol to remove
+ *
+ * Removes a protocol from the allowed protocol list.
+ **/
 void
 nm_setting_wireless_security_remove_proto (NMSettingWirelessSecurity *setting, guint32 i)
 {
@@ -200,6 +279,13 @@ nm_setting_wireless_security_remove_proto (NMSettingWirelessSecurity *setting, g
 	priv->proto = g_slist_delete_link (priv->proto, elt);
 }
 
+/**
+ * nm_setting_wireless_security_clear_protos:
+ * @setting: the #NMSettingWirelessSecurity
+ *
+ * Removes all protocols from the allowed list.  If there are no protocols
+ * specified then all protocols are allowed.
+ **/
 void
 nm_setting_wireless_security_clear_protos (NMSettingWirelessSecurity *setting)
 {
@@ -212,6 +298,12 @@ nm_setting_wireless_security_clear_protos (NMSettingWirelessSecurity *setting)
 	priv->proto = NULL;
 }
 
+/**
+ * nm_setting_wireless_security_get_num_pairwise:
+ * @setting: the #NMSettingWirelessSecurity
+ *
+ * Returns: the number of pairwise encryption algorithms in the allowed list
+ **/
 guint32
 nm_setting_wireless_security_get_num_pairwise (NMSettingWirelessSecurity *setting)
 {
@@ -220,6 +312,16 @@ nm_setting_wireless_security_get_num_pairwise (NMSettingWirelessSecurity *settin
 	return g_slist_length (NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->pairwise);
 }
 
+/**
+ * nm_setting_wireless_security_get_pairwise:
+ * @setting: the #NMSettingWirelessSecurity
+ * @i: index of an item in the allowed pairwise encryption algorithm list
+ *
+ * Returns the allowed pairwise encryption algorithm from allowed algorithm
+ * list.
+ *
+ * Returns: the pairwise encryption algorithm at index @i
+ **/
 const char *
 nm_setting_wireless_security_get_pairwise (NMSettingWirelessSecurity *setting, guint32 i)
 {
@@ -233,6 +335,20 @@ nm_setting_wireless_security_get_pairwise (NMSettingWirelessSecurity *setting, g
 	return (const char *) g_slist_nth_data (priv->pairwise, i);
 }
 
+/**
+ * nm_setting_wireless_security_add_pairwise:
+ * @setting: the #NMSettingWirelessSecurity
+ * @pairwise: the encryption algorithm to add, one of "wep40", "wep104",
+ * "tkip", or "ccmp"
+ *
+ * Adds an encryption algorithm to the list of allowed pairwise encryption
+ * algorithms.  If the list is not empty, then only access points that support
+ * one or more of the encryption algorithms in the list will be considered
+ * compatible with this connection.
+ *
+ * Returns: %TRUE if the algorithm was added to the list, %FALSE if it was
+ * already in the list
+ **/
 gboolean
 nm_setting_wireless_security_add_pairwise (NMSettingWirelessSecurity *setting, const char *pairwise)
 {
@@ -244,7 +360,7 @@ nm_setting_wireless_security_add_pairwise (NMSettingWirelessSecurity *setting, c
 
 	priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
 	for (iter = priv->pairwise; iter; iter = g_slist_next (iter)) {
-		if (!strcmp (pairwise, (char *) iter->data))
+		if (strcasecmp (pairwise, (char *) iter->data) == 0)
 			return FALSE;
 	}
 
@@ -252,6 +368,14 @@ nm_setting_wireless_security_add_pairwise (NMSettingWirelessSecurity *setting, c
 	return TRUE;
 }
 
+/**
+ * nm_setting_wireless_security_remove_pairwise:
+ * @setting: the #NMSettingWirelessSecurity
+ * @i: the index of an item in the allowed pairwise encryption algorithm list
+ *
+ * Removes an encryption algorithm from the allowed pairwise encryption
+ * algorithm list.
+ **/
 void
 nm_setting_wireless_security_remove_pairwise (NMSettingWirelessSecurity *setting, guint32 i)
 {
@@ -268,6 +392,13 @@ nm_setting_wireless_security_remove_pairwise (NMSettingWirelessSecurity *setting
 	priv->pairwise = g_slist_delete_link (priv->pairwise, elt);
 }
 
+/**
+ * nm_setting_wireless_security_clear_pairwise:
+ * @setting: the #NMSettingWirelessSecurity
+ *
+ * Removes all algorithms from the allowed list.  If there are no algorithms
+ * specified then all pairwise encryption algorithms are allowed.
+ **/
 void
 nm_setting_wireless_security_clear_pairwise (NMSettingWirelessSecurity *setting)
 {
@@ -280,6 +411,12 @@ nm_setting_wireless_security_clear_pairwise (NMSettingWirelessSecurity *setting)
 	priv->pairwise = NULL;
 }
 
+/**
+ * nm_setting_wireless_security_get_num_groups:
+ * @setting: the #NMSettingWirelessSecurity
+ *
+ * Returns: the number of groupwise encryption algorithms in the allowed list
+ **/
 guint32
 nm_setting_wireless_security_get_num_groups (NMSettingWirelessSecurity *setting)
 {
@@ -288,6 +425,16 @@ nm_setting_wireless_security_get_num_groups (NMSettingWirelessSecurity *setting)
 	return g_slist_length (NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->group);
 }
 
+/**
+ * nm_setting_wireless_security_get_group:
+ * @setting: the #NMSettingWirelessSecurity
+ * @i: index of an item in the allowed groupwise encryption algorithm list
+ *
+ * Returns the allowed groupwise encryption algorithm from allowed algorithm
+ * list.
+ *
+ * Returns: the groupwise encryption algorithm at index @i
+ **/
 const char *
 nm_setting_wireless_security_get_group (NMSettingWirelessSecurity *setting, guint32 i)
 {
@@ -301,6 +448,20 @@ nm_setting_wireless_security_get_group (NMSettingWirelessSecurity *setting, guin
 	return (const char *) g_slist_nth_data (priv->group, i);
 }
 
+/**
+ * nm_setting_wireless_security_add_group:
+ * @setting: the #NMSettingWirelessSecurity
+ * @group: the encryption algorithm to add, one of "wep40", "wep104",
+ * "tkip", or "ccmp"
+ *
+ * Adds an encryption algorithm to the list of allowed groupwise encryption
+ * algorithms.  If the list is not empty, then only access points that support
+ * one or more of the encryption algorithms in the list will be considered
+ * compatible with this connection.
+ *
+ * Returns: %TRUE if the algorithm was added to the list, %FALSE if it was
+ * already in the list
+ **/
 gboolean
 nm_setting_wireless_security_add_group (NMSettingWirelessSecurity *setting, const char *group)
 {
@@ -312,7 +473,7 @@ nm_setting_wireless_security_add_group (NMSettingWirelessSecurity *setting, cons
 
 	priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
 	for (iter = priv->group; iter; iter = g_slist_next (iter)) {
-		if (!strcmp (group, (char *) iter->data))
+		if (strcasecmp (group, (char *) iter->data) == 0)
 			return FALSE;
 	}
 
@@ -320,6 +481,14 @@ nm_setting_wireless_security_add_group (NMSettingWirelessSecurity *setting, cons
 	return TRUE;
 }
 
+/**
+ * nm_setting_wireless_security_remove_group:
+ * @setting: the #NMSettingWirelessSecurity
+ * @i: the index of an item in the allowed groupwise encryption algorithm list
+ *
+ * Removes an encryption algorithm from the allowed groupwise encryption
+ * algorithm list.
+ **/
 void
 nm_setting_wireless_security_remove_group (NMSettingWirelessSecurity *setting, guint32 i)
 {
@@ -336,6 +505,13 @@ nm_setting_wireless_security_remove_group (NMSettingWirelessSecurity *setting, g
 	priv->group = g_slist_delete_link (priv->group, elt);
 }
 
+/**
+ * nm_setting_wireless_security_clear_groups:
+ * @setting: the #NMSettingWirelessSecurity
+ *
+ * Removes all algorithms from the allowed list.  If there are no algorithms
+ * specified then all groupwise encryption algorithms are allowed.
+ **/
 void
 nm_setting_wireless_security_clear_groups (NMSettingWirelessSecurity *setting)
 {
@@ -348,6 +524,12 @@ nm_setting_wireless_security_clear_groups (NMSettingWirelessSecurity *setting)
 	priv->group = NULL;
 }
 
+/**
+ * nm_setting_wireless_security_get_psk:
+ * @setting: the #NMSettingWirelessSecurity
+ *
+ * Returns: the #NMSettingWirelessSecurity:psk property of the setting
+ **/
 const char *
 nm_setting_wireless_security_get_psk (NMSettingWirelessSecurity *setting)
 {
@@ -371,6 +553,12 @@ nm_setting_wireless_security_get_psk_flags (NMSettingWirelessSecurity *setting)
 	return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->psk_flags;
 }
 
+/**
+ * nm_setting_wireless_security_get_leap_username:
+ * @setting: the #NMSettingWirelessSecurity
+ *
+ * Returns: the #NMSettingWirelessSecurity:leap-username property of the setting
+ **/
 const char *
 nm_setting_wireless_security_get_leap_username (NMSettingWirelessSecurity *setting)
 {
@@ -379,6 +567,12 @@ nm_setting_wireless_security_get_leap_username (NMSettingWirelessSecurity *setti
 	return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->leap_username;
 }
 
+/**
+ * nm_setting_wireless_security_get_leap_password:
+ * @setting: the #NMSettingWirelessSecurity
+ *
+ * Returns: the #NMSettingWirelessSecurity:leap-password property of the setting
+ **/
 const char *
 nm_setting_wireless_security_get_leap_password (NMSettingWirelessSecurity *setting)
 {
@@ -402,6 +596,13 @@ nm_setting_wireless_security_get_leap_password_flags (NMSettingWirelessSecurity
 	return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->leap_password_flags;
 }
 
+/**
+ * nm_setting_wireless_security_get_wep_key:
+ * @setting: the #NMSettingWirelessSecurity
+ * @idx: the WEP key index (0..3 inclusive)
+ *
+ * Returns: the WEP key at the given index
+ **/
 const char *
 nm_setting_wireless_security_get_wep_key (NMSettingWirelessSecurity *setting, guint32 idx)
 {
@@ -424,6 +625,16 @@ nm_setting_wireless_security_get_wep_key (NMSettingWirelessSecurity *setting, gu
 	return NULL;
 }
 
+/**
+ * nm_setting_wireless_security_set_wep_key:
+ * @setting: the #NMSettingWirelessSecurity
+ * @idx: the index of the key (0..3 inclusive)
+ * @key: the WEP key as a string, in either hexadecimal, ASCII, or passphrase
+ * form as determiend by the value of the #NMSettingWirelessSecurity:wep-key-type
+ * property.
+ *
+ * Sets a WEP key in the given index.
+ **/
 void
 nm_setting_wireless_security_set_wep_key (NMSettingWirelessSecurity *setting, guint32 idx, const char *key)
 {
@@ -455,6 +666,12 @@ nm_setting_wireless_security_set_wep_key (NMSettingWirelessSecurity *setting, gu
 	}
 }
 
+/**
+ * nm_setting_wireless_security_get_wep_tx_keyidx:
+ * @setting: the #NMSettingWirelessSecurity
+ *
+ * Returns: the #NMSettingWirelessSecurity:wep-tx-keyidx property of the setting
+ **/
 guint32
 nm_setting_wireless_security_get_wep_tx_keyidx (NMSettingWirelessSecurity *setting)
 {
@@ -463,6 +680,12 @@ nm_setting_wireless_security_get_wep_tx_keyidx (NMSettingWirelessSecurity *setti
 	return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->wep_tx_keyidx;
 }
 
+/**
+ * nm_setting_wireless_security_get_auth_alg:
+ * @setting: the #NMSettingWirelessSecurity
+ *
+ * Returns: the #NMSettingWirelessSecurity:auth-alg property of the setting
+ **/
 const char *
 nm_setting_wireless_security_get_auth_alg (NMSettingWirelessSecurity *setting)
 {
@@ -485,6 +708,12 @@ nm_setting_wireless_security_get_wep_key_flags (NMSettingWirelessSecurity *setti
 	return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->wep_key_flags;
 }
 
+/**
+ * nm_setting_wireless_security_get_wep_key_type:
+ * @setting: the #NMSettingWirelessSecurity
+ *
+ * Returns: the #NMSettingWirelessSecurity:wep-key-type property of the setting
+ **/
 NMWepKeyType
 nm_setting_wireless_security_get_wep_key_type (NMSettingWirelessSecurity *setting)
 {
@@ -1353,9 +1582,8 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting
 	/**
 	 * NMSettingWirelessSecurity:wep-key-type:
 	 *
-	 * Controls the interpretation of WEP keys.  Allowed values are 1 (interpret
-	 * WEP keys as hexadecimal or ASCII keys) or 2 (interpret WEP keys as WEP
-	 * Passphrases).  If set to 1 and the keys are hexadecimal, they must be
+	 * Controls the interpretation of WEP keys.  Allowed values are those given
+	 * by %NMWepKeyType.  If set to 1 and the keys are hexadecimal, they must be
 	 * either 10 or 26 characters in length.  If set to 1 and the keys are
 	 * ASCII keys, they must be either 5 or 13 characters in length.  If set to
 	 * 2, the passphrase is hashed using the de-facto MD5 method to derive the
diff --git a/libnm-util/nm-setting-wireless-security.h b/libnm-util/nm-setting-wireless-security.h
index 743e161f..5f23893a 100644
--- a/libnm-util/nm-setting-wireless-security.h
+++ b/libnm-util/nm-setting-wireless-security.h
@@ -39,8 +39,23 @@ G_BEGIN_DECLS
 
 #define NM_SETTING_WIRELESS_SECURITY_SETTING_NAME "802-11-wireless-security"
 
-typedef enum
-{
+/**
+ * NMSettingWirelessSecurityError:
+ * @NM_SETTING_WIRELESS_SECURITY_ERROR_UNKNOWN: unknown or unclassified error
+ * @NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY: the property was invalid
+ * @NM_SETTING_WIRELESS_SECURITY_ERROR_MISSING_PROPERTY: the property was
+ * missing and is required
+ * @NM_SETTING_WIRELESS_SECURITY_ERROR_MISSING_802_1X_SETTING: a property contained
+ * a value that requires the connection to contain a #NMSetting8021x setting
+ * @NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_802_1X: LEAP authentication
+ * was specified but key management was not set to "8021x"
+ * @NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME: LEAP authentication
+ * was specified but no LEAP username was given
+ * @NM_SETTING_WIRELESS_SECURITY_ERROR_SHARED_KEY_REQUIRES_WEP: Shared Key
+ * authentication was specified but the setting did not specify WEP as the
+ * encryption protocol
+ */
+typedef enum {
 	NM_SETTING_WIRELESS_SECURITY_ERROR_UNKNOWN = 0,
 	NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
 	NM_SETTING_WIRELESS_SECURITY_ERROR_MISSING_PROPERTY,
@@ -56,6 +71,29 @@ GType nm_setting_wireless_security_error_get_type (void);
 #define NM_SETTING_WIRELESS_SECURITY_ERROR nm_setting_wireless_security_error_quark ()
 GQuark nm_setting_wireless_security_error_quark (void);
 
+/**
+ * NMWepKeyType:
+ * @NM_WEP_KEY_TYPE_UNKNOWN: unknown WEP key type
+ * @NM_WEP_KEY_TYPE_KEY: indicates a hexadecimal or ASCII formatted WEP key.
+ * Hex keys are either 10 or 26 hexadecimal characters (ie "5f782f2f5f" or
+ * "732f2d712e4a394a375d366931"), while ASCII keys are either 5 or 13 ASCII
+ * characters (ie "abcde" or "blahblah99$*1").
+ * @NM_WEP_KEY_TYPE_PASSPHRASE: indicates a WEP passphrase (ex "I bought a duck
+ * on my way back from the market 235Q&^%^*%") instead of a hexadecimal or ASCII
+ * key.  Passphrases are between 8 and 64 characters inclusive and are hashed
+ * the actual WEP key using the MD5 hash algorithm.
+ * @NM_WEP_KEY_TYPE_LAST: placeholder value for bounds-checking
+ *
+ * The #NMWepKeyType values specify how any WEP keys present in the setting
+ * are intepreted.  There are no standards governing how to hash the various WEP
+ * key/passphrase formats into the actual WEP key.  Unfortunately some WEP keys
+ * can be interpreted in multiple ways, requring the setting to specify how to
+ * interpret the any WEP keys.  For example, the key "732f2d712e4a394a375d366931"
+ * is both a valid Hexadecimal WEP key and a WEP passphrase.  Further, many
+ * ASCII keys are also valid WEP passphrases, but since passphrases and ASCII
+ * keys are hashed differently to determine the actual WEP key the type must be
+ * specified.
+ */
 typedef enum {
 	NM_WEP_KEY_TYPE_UNKNOWN = 0,
 	NM_WEP_KEY_TYPE_KEY = 1,          /* Hex or ASCII */
diff --git a/libnm-util/nm-setting-wireless.c b/libnm-util/nm-setting-wireless.c
index 1e243f0f..37ad07ab 100644
--- a/libnm-util/nm-setting-wireless.c
+++ b/libnm-util/nm-setting-wireless.c
@@ -19,7 +19,7 @@
  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301 USA.
  *
- * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ * (C) Copyright 2007 - 2011 Red Hat, Inc.
  * (C) Copyright 2007 - 2008 Novell, Inc.
  */
 
@@ -37,6 +37,22 @@
 #include "nm-dbus-glib-types.h"
 #include "nm-utils-private.h"
 
+/**
+ * SECTION:nm-setting-wireless
+ * @short_description: Describes connection properties for 802.11 WiFi networks
+ * @include: nm-setting-wireless.h
+ *
+ * The #NMSettingWireless object is a #NMSetting subclass that describes properties
+ * necessary for connection to 802.11 WiFi networks.
+ **/
+
+/**
+ * nm_setting_wireless_error_quark:
+ *
+ * Registers an error quark for #NMSettingWireless if necessary.
+ *
+ * Returns: the error quark used for #NMSettingWireless errors.
+ **/
 GQuark
 nm_setting_wireless_error_quark (void)
 {
@@ -89,6 +105,7 @@ typedef struct {
 	guint32 tx_power;
 	GByteArray *device_mac_address;
 	GByteArray *cloned_mac_address;
+	GSList *mac_address_blacklist;
 	guint32 mtu;
 	GSList *seen_bssids;
 	char *security;
@@ -105,6 +122,7 @@ enum {
 	PROP_TX_POWER,
 	PROP_MAC_ADDRESS,
 	PROP_CLONED_MAC_ADDRESS,
+	PROP_MAC_ADDRESS_BLACKLIST,
 	PROP_MTU,
 	PROP_SEEN_BSSIDS,
 	PROP_SEC,
@@ -128,6 +146,27 @@ match_cipher (const char *cipher,
 	return TRUE;
 }
 
+/**
+ * nm_setting_wireless_ap_security_compatible:
+ * @s_wireless: a #NMSettingWireless
+ * @s_wireless_sec: a #NMSettingWirelessSecurity or %NULL
+ * @ap_flags: the %NM80211ApFlags of the given access point
+ * @ap_wpa: the %NM80211ApSecurityFlags of the given access point's WPA
+ * capabilities
+ * @ap_rsn: the %NM80211ApSecurityFlags of the given access point's WPA2/RSN
+ * capabilities
+ * @ap_mode: the 802.11 mode of the AP, either Ad-Hoc or Infrastructure
+ *
+ * Given a #NMSettingWireless and an optional #NMSettingWirelessSecurity,
+ * determine if the configuration given by the settings is compatible with
+ * the security of an access point using that access point's capability flags
+ * and mode.  Useful for clients that wish to filter a set of connections
+ * against a set of access points and determine which connections are
+ * compatible with which access points.
+ *
+ * Returns: %TRUE if the given settings are compatible with the access point's
+ * security flags and mode, %FALSE if they are not.
+ */ 
 gboolean
 nm_setting_wireless_ap_security_compatible (NMSettingWireless *s_wireless,
                                             NMSettingWirelessSecurity *s_wireless_sec,
@@ -289,12 +328,25 @@ nm_setting_wireless_ap_security_compatible (NMSettingWireless *s_wireless,
 	return FALSE;
 }
 
+/**
+ * nm_setting_wireless_new:
+ *
+ * Creates a new #NMSettingWireless object with default values.
+ *
+ * Returns: (transfer full): the new empty #NMSettingWireless object
+ **/
 NMSetting *
 nm_setting_wireless_new (void)
 {
 	return (NMSetting *) g_object_new (NM_TYPE_SETTING_WIRELESS, NULL);
 }
 
+/**
+ * nm_setting_wireless_get_ssid:
+ * @setting: the #NMSettingWireless
+ *
+ * Returns: the #NMSettingWireless:ssid property of the setting
+ **/
 const GByteArray *
 nm_setting_wireless_get_ssid (NMSettingWireless *setting)
 {
@@ -303,6 +355,12 @@ nm_setting_wireless_get_ssid (NMSettingWireless *setting)
 	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->ssid;
 }
 
+/**
+ * nm_setting_wireless_get_mode:
+ * @setting: the #NMSettingWireless
+ *
+ * Returns: the #NMSettingWireless:mode property of the setting
+ **/
 const char *
 nm_setting_wireless_get_mode (NMSettingWireless *setting)
 {
@@ -311,6 +369,12 @@ nm_setting_wireless_get_mode (NMSettingWireless *setting)
 	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mode;
 }
 
+/**
+ * nm_setting_wireless_get_band:
+ * @setting: the #NMSettingWireless
+ *
+ * Returns: the #NMSettingWireless:band property of the setting
+ **/
 const char *
 nm_setting_wireless_get_band (NMSettingWireless *setting)
 {
@@ -319,6 +383,12 @@ nm_setting_wireless_get_band (NMSettingWireless *setting)
 	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->band;
 }
 
+/**
+ * nm_setting_wireless_get_channel:
+ * @setting: the #NMSettingWireless
+ *
+ * Returns: the #NMSettingWireless:channel property of the setting
+ **/
 guint32
 nm_setting_wireless_get_channel (NMSettingWireless *setting)
 {
@@ -327,6 +397,12 @@ nm_setting_wireless_get_channel (NMSettingWireless *setting)
 	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->channel;
 }
 
+/**
+ * nm_setting_wireless_get_bssid:
+ * @setting: the #NMSettingWireless
+ *
+ * Returns: the #NMSettingWireless:bssid property of the setting
+ **/
 const GByteArray *
 nm_setting_wireless_get_bssid (NMSettingWireless *setting)
 {
@@ -335,6 +411,12 @@ nm_setting_wireless_get_bssid (NMSettingWireless *setting)
 	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->bssid;
 }
 
+/**
+ * nm_setting_wireless_get_rate:
+ * @setting: the #NMSettingWireless
+ *
+ * Returns: the #NMSettingWireless:rate property of the setting
+ **/
 guint32
 nm_setting_wireless_get_rate (NMSettingWireless *setting)
 {
@@ -343,6 +425,12 @@ nm_setting_wireless_get_rate (NMSettingWireless *setting)
 	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->rate;
 }
 
+/**
+ * nm_setting_wireless_get_tx_power:
+ * @setting: the #NMSettingWireless
+ *
+ * Returns: the #NMSettingWireless:tx-power property of the setting
+ **/
 guint32
 nm_setting_wireless_get_tx_power (NMSettingWireless *setting)
 {
@@ -351,6 +439,12 @@ nm_setting_wireless_get_tx_power (NMSettingWireless *setting)
 	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->tx_power;
 }
 
+/**
+ * nm_setting_wireless_get_mac_address:
+ * @setting: the #NMSettingWireless
+ *
+ * Returns: the #NMSettingWireless:mac-address property of the setting
+ **/
 const GByteArray *
 nm_setting_wireless_get_mac_address (NMSettingWireless *setting)
 {
@@ -359,6 +453,12 @@ nm_setting_wireless_get_mac_address (NMSettingWireless *setting)
 	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->device_mac_address;
 }
 
+/**
+ * nm_setting_wireless_get_cloned_mac_address:
+ * @setting: the #NMSettingWireless
+ *
+ * Returns: the #NMSettingWireless:cloned-mac-address property of the setting
+ **/
 const GByteArray *
 nm_setting_wireless_get_cloned_mac_address (NMSettingWireless *setting)
 {
@@ -367,6 +467,27 @@ nm_setting_wireless_get_cloned_mac_address (NMSettingWireless *setting)
 	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->cloned_mac_address;
 }
 
+/**
+ * nm_setting_wireless_get_mac_address_blacklist:
+ * @setting: the #NMSettingWireless
+ *
+ * Returns: (element-type GLib.ByteArray): the
+ * #NMSettingWireless:mac-address-blacklist property of the setting
+ **/
+const GSList *
+nm_setting_wireless_get_mac_address_blacklist (NMSettingWireless *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL);
+
+	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mac_address_blacklist;
+}
+
+/**
+ * nm_setting_wireless_get_mtu:
+ * @setting: the #NMSettingWireless
+ *
+ * Returns: the #NMSettingWireless:mtu property of the setting
+ **/
 guint32
 nm_setting_wireless_get_mtu (NMSettingWireless *setting)
 {
@@ -375,6 +496,12 @@ nm_setting_wireless_get_mtu (NMSettingWireless *setting)
 	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mtu;
 }
 
+/**
+ * nm_setting_wireless_get_security:
+ * @setting: the #NMSettingWireless
+ *
+ * Returns: the #NMSettingWireless:security property of the setting
+ **/
 const char *
 nm_setting_wireless_get_security (NMSettingWireless *setting)
 {
@@ -383,6 +510,17 @@ nm_setting_wireless_get_security (NMSettingWireless *setting)
 	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->security;
 }
 
+/**
+ * nm_setting_wireless_add_seen_bssid:
+ * @setting: the #NMSettingWireless
+ * @bssid: the new BSSID to add to the list
+ *
+ * Adds a new WiFi AP's BSSID to the previously seen BSSID list of the setting.
+ * NetworkManager tracks previously seen BSSIDs internally so this function
+ * no longer has much use.
+ *
+ * Returns: %TRUE if @bssid was already known, %FALSE if not
+ **/
 gboolean
 nm_setting_wireless_add_seen_bssid (NMSettingWireless *setting,
 									const char *bssid)
@@ -416,6 +554,12 @@ nm_setting_wireless_add_seen_bssid (NMSettingWireless *setting,
 	return !found;
 }
 
+/**
+ * nm_setting_wireless_get_num_seen_bssids:
+ * @setting: the #NMSettingWireless
+ *
+ * Returns: the number of BSSIDs in the previously seen BSSID list
+ **/
 guint32
 nm_setting_wireless_get_num_seen_bssids (NMSettingWireless *setting)
 {
@@ -424,6 +568,13 @@ nm_setting_wireless_get_num_seen_bssids (NMSettingWireless *setting)
 	return g_slist_length (NM_SETTING_WIRELESS_GET_PRIVATE (setting)->seen_bssids);
 }
 
+/**
+ * nm_setting_wireless_get_seen_bssid:
+ * @setting: the #NMSettingWireless
+ * @i: index of a BSSID in the previously seen BSSID list
+ *
+ * Returns: the BSSID at index @i
+ **/
 const char *
 nm_setting_wireless_get_seen_bssid (NMSettingWireless *setting,
 									guint32 i)
@@ -524,6 +675,18 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
 		return FALSE;
 	}
 
+	for (iter = priv->mac_address_blacklist; iter; iter = iter->next) {
+		struct ether_addr addr;
+
+		if (!ether_aton_r (iter->data, &addr)) {
+			g_set_error (error,
+			             NM_SETTING_WIRELESS_ERROR,
+			             NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
+			             NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST);
+			return FALSE;
+		}
+	}
+
 	for (iter = priv->seen_bssids; iter; iter = iter->next) {
 		struct ether_addr addr;
 
@@ -571,7 +734,7 @@ finalize (GObject *object)
 		g_byte_array_free (priv->device_mac_address, TRUE);
 	if (priv->cloned_mac_address)
 		g_byte_array_free (priv->cloned_mac_address, TRUE);
-
+	nm_utils_slist_free (priv->mac_address_blacklist, g_free);
 	nm_utils_slist_free (priv->seen_bssids, g_free);
 
 	G_OBJECT_CLASS (nm_setting_wireless_parent_class)->finalize (object);
@@ -621,6 +784,10 @@ set_property (GObject *object, guint prop_id,
 			g_byte_array_free (priv->cloned_mac_address, TRUE);
 		priv->cloned_mac_address = g_value_dup_boxed (value);
 		break;
+	case PROP_MAC_ADDRESS_BLACKLIST:
+		nm_utils_slist_free (priv->mac_address_blacklist, g_free);
+		priv->mac_address_blacklist = g_value_dup_boxed (value);
+		break;
 	case PROP_MTU:
 		priv->mtu = g_value_get_uint (value);
 		break;
@@ -672,6 +839,9 @@ get_property (GObject *object, guint prop_id,
 	case PROP_CLONED_MAC_ADDRESS:
 		g_value_set_boxed (value, nm_setting_wireless_get_cloned_mac_address (setting));
 		break;
+	case PROP_MAC_ADDRESS_BLACKLIST:
+		g_value_set_boxed (value, nm_setting_wireless_get_mac_address_blacklist (setting));
+		break;
 	case PROP_MTU:
 		g_value_set_uint (value, nm_setting_wireless_get_mtu (setting));
 		break;
@@ -869,31 +1039,41 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
 	                                     G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
 
 	/**
+	 * NMSettingWireless:mac-address-blacklist:
+	 *
+	 * If specified, this connection will never apply to the WiFi 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).
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_MAC_ADDRESS_BLACKLIST,
+		 _nm_param_spec_specialized (NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST,
+		                             "MAC Address Blacklist",
+		                             "If specified, this connection will never apply to "
+		                             "the WiFi 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).",
+		                             DBUS_TYPE_G_LIST_OF_STRING,
+		                             G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE));
+
+	/**
 	 * NMSettingWireless:seen-bssids:
 	 *
 	 * A list of BSSIDs (each BSSID formatted as a MAC address like
 	 * '00:11:22:33:44:55') that have been detected as part of the WiFI network.
-	 * The settings service will usually populate this property by periodically
-	 * asking NetworkManager what the device's current AP is while connected
-	 * to the network (or monitoring the device's 'active-ap' property) and
-	 * adding the current AP'sBSSID to this list.  This list helps NetworkManager
-	 * find hidden APs by matching up scan results with the BSSIDs in this list.
+	 * NetworkManager internally tracks previously seen BSSIDs so this property
+	 * is no longer of much use.
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_SEEN_BSSIDS,
 		 _nm_param_spec_specialized (NM_SETTING_WIRELESS_SEEN_BSSIDS,
 							   "Seen BSSIDS",
 							   "A list of BSSIDs (each BSSID formatted as a MAC "
-							   "address like '00:11:22:33:44:55') that have been "
-							   "detected as part of the WiFI network.  The "
-							   "settings service will usually populate this "
-							   "property by periodically asking NetworkManager "
-							   "what the device's current AP is while connected "
-							   "to the network (or monitoring the device's "
-							   "'active-ap' property) and adding the current AP's "
-							   "BSSID to this list.  This list helps NetworkManager "
-							   "find hidden APs by matching up scan results with "
-							   "the BSSIDs in this list.",
+							   "address like 00:11:22:33:44:55') that have been "
+							   "detected as part of the WiFI network. "
+							   "NetworkManager internally tracks previously seen "
+							   "BSSIDs so this property is no longer of much use.",
 							   DBUS_TYPE_G_LIST_OF_STRING,
 							   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE));
 
diff --git a/libnm-util/nm-setting-wireless.h b/libnm-util/nm-setting-wireless.h
index d3e1ed41..746466be 100644
--- a/libnm-util/nm-setting-wireless.h
+++ b/libnm-util/nm-setting-wireless.h
@@ -19,7 +19,7 @@
  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301 USA.
  *
- * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ * (C) Copyright 2007 - 2011 Red Hat, Inc.
  * (C) Copyright 2007 - 2008 Novell, Inc.
  */
 
@@ -41,8 +41,18 @@ G_BEGIN_DECLS
 
 #define NM_SETTING_WIRELESS_SETTING_NAME "802-11-wireless"
 
-typedef enum
-{
+/**
+ * NMSettingWirelessError:
+ * @NM_SETTING_WIRELESS_ERROR_UNKNOWN: unknown or unclassified error
+ * @NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY: the property was invalid
+ * @NM_SETTING_WIRELESS_ERROR_MISSING_PROPERTY: the property was missing and is
+ * required
+ * @NM_SETTING_WIRELESS_ERROR_MISSING_SECURITY_SETTING: property values require
+ * the presence of an #NMSettingWirelessSecurity object in the connection
+ * @NM_SETTING_WIRELESS_ERROR_CHANNEL_REQUIRES_BAND: the property channel was
+ * set to a value that requires the #NMSettingWireless:band property to be set
+ */
+typedef enum {
 	NM_SETTING_WIRELESS_ERROR_UNKNOWN = 0,
 	NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
 	NM_SETTING_WIRELESS_ERROR_MISSING_PROPERTY,
@@ -65,11 +75,24 @@ GQuark nm_setting_wireless_error_quark (void);
 #define NM_SETTING_WIRELESS_TX_POWER    "tx-power"
 #define NM_SETTING_WIRELESS_MAC_ADDRESS "mac-address"
 #define NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS "cloned-mac-address"
+#define NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST "mac-address-blacklist"
 #define NM_SETTING_WIRELESS_MTU         "mtu"
 #define NM_SETTING_WIRELESS_SEEN_BSSIDS "seen-bssids"
 #define NM_SETTING_WIRELESS_SEC         "security"
 
+/**
+ * NM_SETTING_WIRELESS_MODE_ADHOC:
+ *
+ * Indicates Ad-Hoc mode where no access point is expected to be present.
+ */
 #define NM_SETTING_WIRELESS_MODE_ADHOC  "adhoc"
+
+/**
+ * NM_SETTING_WIRELESS_MODE_INFRA
+ *
+ * Indicates infrastructure mode where an access point is expected to be present
+ * for this connection.
+ */
 #define NM_SETTING_WIRELESS_MODE_INFRA  "infrastructure"
 
 typedef struct {
@@ -99,6 +122,7 @@ guint32           nm_setting_wireless_get_rate               (NMSettingWireless
 guint32           nm_setting_wireless_get_tx_power           (NMSettingWireless *setting);
 const GByteArray *nm_setting_wireless_get_mac_address        (NMSettingWireless *setting);
 const GByteArray *nm_setting_wireless_get_cloned_mac_address (NMSettingWireless *setting);
+const GSList     *nm_setting_wireless_get_mac_address_blacklist (NMSettingWireless *setting);
 guint32           nm_setting_wireless_get_mtu                (NMSettingWireless *setting);
 const char       *nm_setting_wireless_get_security           (NMSettingWireless *setting);
 
diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c
index 3fe90db2..3573f888 100644
--- a/libnm-util/nm-setting.c
+++ b/libnm-util/nm-setting.c
@@ -332,27 +332,52 @@ nm_setting_verify (NMSetting *setting, GSList *all_settings, GError **error)
 	return TRUE;
 }
 
-static inline gboolean
-should_compare_prop (NMSetting *setting,
-                     const char *prop_name,
-                     NMSettingCompareFlags comp_flags,
-                     GParamFlags prop_flags)
+static gboolean
+compare_property (NMSetting *setting,
+	              NMSetting *other,
+	              const GParamSpec *prop_spec,
+	              NMSettingCompareFlags flags)
 {
-	/* Fuzzy compare ignores secrets and properties defined with the FUZZY_IGNORE flag */
-	if (   (comp_flags & NM_SETTING_COMPARE_FLAG_FUZZY)
-	    && (prop_flags & (NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_SECRET)))
-		return FALSE;
+	GValue value1 = { 0 };
+	GValue value2 = { 0 };
+	gboolean different;
 
-	if (   (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS)
-	    && (prop_flags & NM_SETTING_PARAM_SECRET))
-		return FALSE;
+	/* Handle compare flags */
+	if (prop_spec->flags & NM_SETTING_PARAM_SECRET) {
+		NMSettingSecretFlags a_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+		NMSettingSecretFlags b_secret_flags = NM_SETTING_SECRET_FLAG_NONE;
 
-	if (   (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_ID)
-	    && NM_IS_SETTING_CONNECTION (setting)
-	    && !strcmp (prop_name, NM_SETTING_CONNECTION_ID))
-		return FALSE;
+		nm_setting_get_secret_flags (setting, prop_spec->name, &a_secret_flags, NULL);
+		nm_setting_get_secret_flags (other, prop_spec->name, &b_secret_flags, NULL);
 
-	return TRUE;
+		/* If the secret flags aren't the same the settings aren't the same */
+		if (a_secret_flags != b_secret_flags)
+			return FALSE;
+
+		/* Check for various secret flags that might cause us to ignore comparing
+		 * this property.
+		 */
+		if (   (flags & NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS)
+		    && (a_secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED))
+			return TRUE;
+
+		if (   (flags & NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)
+		    && (a_secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED))
+			return TRUE;
+	}
+
+	g_value_init (&value1, prop_spec->value_type);
+	g_object_get_property (G_OBJECT (setting), prop_spec->name, &value1);
+
+	g_value_init (&value2, prop_spec->value_type);
+	g_object_get_property (G_OBJECT (other), prop_spec->name, &value2);
+
+	different = g_param_values_cmp ((GParamSpec *) prop_spec, &value1, &value2);
+
+	g_value_unset (&value1);
+	g_value_unset (&value2);
+
+	return different == 0 ? TRUE : FALSE;
 }
 
 /**
@@ -374,7 +399,7 @@ nm_setting_compare (NMSetting *a,
 {
 	GParamSpec **property_specs;
 	guint n_property_specs;
-	gint different;
+	gint same = TRUE;
 	guint i;
 
 	g_return_val_if_fail (NM_IS_SETTING (a), FALSE);
@@ -386,32 +411,59 @@ nm_setting_compare (NMSetting *a,
 
 	/* And now all properties */
 	property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (a), &n_property_specs);
-	different = FALSE;
-
-	for (i = 0; i < n_property_specs && !different; i++) {
+	for (i = 0; i < n_property_specs && same; i++) {
 		GParamSpec *prop_spec = property_specs[i];
-		GValue value1 = { 0 };
-		GValue value2 = { 0 };
 
-		/* Handle compare flags */
-		if (!should_compare_prop (a, prop_spec->name, flags, prop_spec->flags))
+		/* Fuzzy compare ignores secrets and properties defined with the FUZZY_IGNORE flag */
+		if (   (flags & NM_SETTING_COMPARE_FLAG_FUZZY)
+			&& (prop_spec->flags & (NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_SECRET)))
 			continue;
 
-		g_value_init (&value1, prop_spec->value_type);
-		g_object_get_property (G_OBJECT (a), prop_spec->name, &value1);
+		if (   (flags & NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS)
+		    && (prop_spec->flags & NM_SETTING_PARAM_SECRET))
+			continue;
+
+		same = NM_SETTING_GET_CLASS (a)->compare_property (a, b, prop_spec, flags);
+	}
+	g_free (property_specs);
 
-		g_value_init (&value2, prop_spec->value_type);
-		g_object_get_property (G_OBJECT (b), prop_spec->name, &value2);
+	return same;
+}
 
-		different = g_param_values_cmp (prop_spec, &value1, &value2);
+static inline gboolean
+should_compare_prop (NMSetting *setting,
+                     const char *prop_name,
+                     NMSettingCompareFlags comp_flags,
+                     GParamFlags prop_flags)
+{
+	/* Fuzzy compare ignores secrets and properties defined with the FUZZY_IGNORE flag */
+	if (   (comp_flags & NM_SETTING_COMPARE_FLAG_FUZZY)
+	    && (prop_flags & (NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_SECRET)))
+		return FALSE;
 
-		g_value_unset (&value1);
-		g_value_unset (&value2);
+	if (prop_flags & NM_SETTING_PARAM_SECRET) {
+		NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+
+		if (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS)
+			return FALSE;
+
+		nm_setting_get_secret_flags (setting, prop_name, &secret_flags, NULL);
+
+		if (   (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS)
+		    && (secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED))
+			return FALSE;
+
+		if (   (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)
+		    && (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED))
+			return FALSE;
 	}
 
-	g_free (property_specs);
+	if (   (comp_flags & NM_SETTING_COMPARE_FLAG_IGNORE_ID)
+	    && NM_IS_SETTING_CONNECTION (setting)
+	    && !strcmp (prop_name, NM_SETTING_CONNECTION_ID))
+		return FALSE;
 
-	return different == 0 ? TRUE : FALSE;
+	return TRUE;
 }
 
 /**
@@ -976,6 +1028,7 @@ nm_setting_class_init (NMSettingClass *setting_class)
 	setting_class->update_one_secret = update_one_secret;
 	setting_class->get_secret_flags = get_secret_flags;
 	setting_class->set_secret_flags = set_secret_flags;
+	setting_class->compare_property = compare_property;
 
 	/* Properties */
 
diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h
index ef3011ad..e21efd81 100644
--- a/libnm-util/nm-setting.h
+++ b/libnm-util/nm-setting.h
@@ -112,6 +112,35 @@ typedef enum {
 } NMSettingSecretFlags;
 
 /**
+ * NMSettingCompareFlags:
+ * @NM_SETTING_COMPARE_FLAG_EXACT: match all properties exactly
+ * @NM_SETTING_COMPARE_FLAG_FUZZY: match only important attributes, like SSID,
+ *   type, security settings, etc.  Does not match, for example, connection ID
+ *   or UUID.
+ * @NM_SETTING_COMPARE_FLAG_IGNORE_ID: ignore the connection's ID
+ * @NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS: ignore all secrets
+ * @NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS: ignore secrets for which
+ * the secret's flags indicate the secret is owned by a user secret agent
+ * (ie, the secret's flag includes @NM_SETTING_SECRET_FLAG_AGENT_OWNED)
+ * @NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS: ignore secrets for which
+ * the secret's flags indicate the secret should not be saved to persistent
+ * storage (ie, the secret's flag includes @NM_SETTING_SECRET_FLAG_NOT_SAVED)
+ *
+ * These flags modify the comparison behavior when comparing two settings or
+ * two connections.
+ *
+ **/
+typedef enum {
+	NM_SETTING_COMPARE_FLAG_EXACT = 0x00000000,
+	NM_SETTING_COMPARE_FLAG_FUZZY = 0x00000001,
+	NM_SETTING_COMPARE_FLAG_IGNORE_ID = 0x00000002,
+	NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS = 0x00000004,
+	NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS = 0x00000008,
+	NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS = 0x00000010
+} NMSettingCompareFlags;
+
+
+/**
  * NMSetting:
  *
  * The NMSetting struct contains only private data.
@@ -148,13 +177,27 @@ typedef struct {
 	                                  NMSettingSecretFlags flags,
 	                                  GError **error);
 
+	/* Returns TRUE if the given property contains the same value in both settings */
+	gboolean    (*compare_property)  (NMSetting *setting,
+	                                  NMSetting *other,
+	                                  const GParamSpec *prop_spec,
+	                                  NMSettingCompareFlags flags);
+
 	/* Padding for future expansion */
 	void (*_reserved1) (void);
 	void (*_reserved2) (void);
 	void (*_reserved3) (void);
-	void (*_reserved4) (void);
 } NMSettingClass;
 
+/**
+ * NMSettingValueIterFn:
+ * @setting: The setting for which properties are being iterated, given to
+ * nm_setting_enumerate_values()
+ * @key: The value/property name
+ * @value: The property's value
+ * @flags: The property's flags, like %NM_SETTING_PARAM_SECRET
+ * @user_data: User data passed to nm_setting_enumerate_values()
+ */
 typedef void (*NMSettingValueIterFn) (NMSetting *setting,
                                       const char *key,
                                       const GValue *value,
@@ -194,26 +237,6 @@ gboolean    nm_setting_verify        (NMSetting *setting,
                                       GSList    *all_settings,
                                       GError    **error);
 
-/**
- * NMSettingCompareFlags:
- * @NM_SETTING_COMPARE_FLAG_EXACT: match all properties exactly
- * @NM_SETTING_COMPARE_FLAG_FUZZY: match only important attributes, like SSID,
- *   type, security settings, etc.  Does not match, for example, connection ID
- *   or UUID.
- * @NM_SETTING_COMPARE_FLAG_IGNORE_ID: ignore the connection's ID
- * @NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS: ignore secrets
- *
- * These flags modify the comparison behavior when comparing two settings or
- * two connections.
- *
- **/
-typedef enum {
-	NM_SETTING_COMPARE_FLAG_EXACT = 0x00000000,
-	NM_SETTING_COMPARE_FLAG_FUZZY = 0x00000001,
-	NM_SETTING_COMPARE_FLAG_IGNORE_ID = 0x00000002,
-	NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS = 0x00000004
-} NMSettingCompareFlags;
-
 gboolean    nm_setting_compare       (NMSetting *a,
                                       NMSetting *b,
                                       NMSettingCompareFlags flags);
diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c
index 449deb1c..d8bcf349 100644
--- a/libnm-util/nm-utils.c
+++ b/libnm-util/nm-utils.c
@@ -1192,12 +1192,12 @@ device_supports_ap_ciphers (guint32 dev_caps,
  **/
 gboolean
 nm_utils_security_valid (NMUtilsSecurityType type,
-                         guint32 wifi_caps,
+                         NMDeviceWifiCapabilities wifi_caps,
                          gboolean have_ap,
                          gboolean adhoc,
-                         guint32 ap_flags,
-                         guint32 ap_wpa,
-                         guint32 ap_rsn)
+                         NM80211ApFlags ap_flags,
+                         NM80211ApSecurityFlags ap_wpa,
+                         NM80211ApSecurityFlags ap_rsn)
 {
 	gboolean good = TRUE;
 
diff --git a/libnm-util/nm-utils.h b/libnm-util/nm-utils.h
index e4714a96..6a179268 100644
--- a/libnm-util/nm-utils.h
+++ b/libnm-util/nm-utils.h
@@ -48,6 +48,24 @@ GHashTable *nm_utils_gvalue_hash_dup  (GHashTable *hash);
 
 void        nm_utils_slist_free    (GSList *list, GDestroyNotify elem_destroy_fn);
 
+/**
+ * NMUtilsSecurityType:
+ * @NMU_SEC_INVALID: unknown or invalid security, placeholder and not used
+ * @NMU_SEC_NONE: unencrypted and open
+ * @NMU_SEC_STATIC_WEP: static WEP keys are used for encryption
+ * @NMU_SEC_LEAP: Cisco LEAP is used for authentication and for generating the
+ * dynamic WEP keys automatically
+ * @NMU_SEC_DYNAMIC_WEP: standard 802.1x is used for authentication and
+ * generating the dynamic WEP keys automatically
+ * @NMU_SEC_WPA_PSK: WPA1 is used with Pre-Shared Keys (PSK)
+ * @NMU_SEC_WPA_ENTERPRISE: WPA1 is used with 802.1x authentication
+ * @NMU_SEC_WPA2_PSK: WPA2/RSN is used with Pre-Shared Keys (PSK)
+ * @NMU_SEC_WPA2_ENTERPRISE: WPA2 is used with 802.1x authentication
+ *
+ * Describes generic security mechanisms that 802.11 access points may offer.
+ * Used with nm_utils_security_valid() for checking whether a given access
+ * point is compatible with a network device.
+ **/
 typedef enum {
 	NMU_SEC_INVALID = 0,
 	NMU_SEC_NONE,
@@ -61,12 +79,12 @@ typedef enum {
 } NMUtilsSecurityType;
 
 gboolean nm_utils_security_valid (NMUtilsSecurityType type,
-                                  guint32 wifi_caps,
+                                  NMDeviceWifiCapabilities wifi_caps,
                                   gboolean have_ap,
                                   gboolean adhoc,
-                                  guint32 ap_flags,
-                                  guint32 ap_wpa,
-                                  guint32 ap_rsn);
+                                  NM80211ApFlags ap_flags,
+                                  NM80211ApSecurityFlags ap_wpa,
+                                  NM80211ApSecurityFlags ap_rsn);
 
 GSList *nm_utils_ip4_addresses_from_gvalue (const GValue *value);
 void nm_utils_ip4_addresses_to_gvalue (GSList *list, GValue *value);
@@ -95,11 +113,11 @@ GByteArray *nm_utils_rsa_key_encrypt (const GByteArray *data,
                                       char **out_password,
                                       GError **error);
 
-G_END_DECLS
-
 guint32 nm_utils_wifi_freq_to_channel (guint32 freq);
 guint32 nm_utils_wifi_channel_to_freq (guint32 channel, const char *band);
 guint32 nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band);
 gboolean nm_utils_wifi_is_channel_valid (guint32 channel, const char *band);
 
+G_END_DECLS
+
 #endif /* NM_UTILS_H */
diff --git a/libnm-util/tests/test-general.c b/libnm-util/tests/test-general.c
index 87a50d67..f2f7e8ff 100644
--- a/libnm-util/tests/test-general.c
+++ b/libnm-util/tests/test-general.c
@@ -852,16 +852,17 @@ test_connection_diff_a_only (void)
 			{ NULL, NM_SETTING_DIFF_RESULT_UNKNOWN }
 		} },
 		{ NM_SETTING_WIRED_SETTING_NAME, {
-			{ NM_SETTING_WIRED_PORT,               NM_SETTING_DIFF_RESULT_IN_A },
-			{ NM_SETTING_WIRED_SPEED,              NM_SETTING_DIFF_RESULT_IN_A },
-			{ NM_SETTING_WIRED_DUPLEX,             NM_SETTING_DIFF_RESULT_IN_A },
-			{ NM_SETTING_WIRED_AUTO_NEGOTIATE,     NM_SETTING_DIFF_RESULT_IN_A },
-			{ NM_SETTING_WIRED_MAC_ADDRESS,        NM_SETTING_DIFF_RESULT_IN_A },
-			{ NM_SETTING_WIRED_CLONED_MAC_ADDRESS, NM_SETTING_DIFF_RESULT_IN_A },
-			{ NM_SETTING_WIRED_MTU,                NM_SETTING_DIFF_RESULT_IN_A },
-			{ NM_SETTING_WIRED_S390_SUBCHANNELS,   NM_SETTING_DIFF_RESULT_IN_A },
-			{ NM_SETTING_WIRED_S390_NETTYPE,       NM_SETTING_DIFF_RESULT_IN_A },
-			{ NM_SETTING_WIRED_S390_OPTIONS,       NM_SETTING_DIFF_RESULT_IN_A },
+			{ NM_SETTING_WIRED_PORT,                  NM_SETTING_DIFF_RESULT_IN_A },
+			{ NM_SETTING_WIRED_SPEED,                 NM_SETTING_DIFF_RESULT_IN_A },
+			{ NM_SETTING_WIRED_DUPLEX,                NM_SETTING_DIFF_RESULT_IN_A },
+			{ NM_SETTING_WIRED_AUTO_NEGOTIATE,        NM_SETTING_DIFF_RESULT_IN_A },
+			{ NM_SETTING_WIRED_MAC_ADDRESS,           NM_SETTING_DIFF_RESULT_IN_A },
+			{ NM_SETTING_WIRED_CLONED_MAC_ADDRESS,    NM_SETTING_DIFF_RESULT_IN_A },
+			{ NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, NM_SETTING_DIFF_RESULT_IN_A },
+			{ NM_SETTING_WIRED_MTU,                   NM_SETTING_DIFF_RESULT_IN_A },
+			{ NM_SETTING_WIRED_S390_SUBCHANNELS,      NM_SETTING_DIFF_RESULT_IN_A },
+			{ NM_SETTING_WIRED_S390_NETTYPE,          NM_SETTING_DIFF_RESULT_IN_A },
+			{ NM_SETTING_WIRED_S390_OPTIONS,          NM_SETTING_DIFF_RESULT_IN_A },
 			{ NULL, NM_SETTING_DIFF_RESULT_UNKNOWN },
 		} },
 		{ NM_SETTING_IP4_CONFIG_SETTING_NAME, {
@@ -1205,14 +1206,101 @@ test_connection_bad_base_types (void)
 	g_clear_error (&error);
 }
 
+static void
+test_setting_compare_id (void)
+{
+	NMSetting *old, *new;
+	gboolean success;
+
+	old = nm_setting_connection_new ();
+	g_object_set (old,
+	              NM_SETTING_CONNECTION_ID, "really awesome cool connection",
+	              NM_SETTING_CONNECTION_UUID, "fbbd59d5-acab-4e30-8f86-258d272617e7",
+	              NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
+	              NULL);
+
+	new = nm_setting_duplicate (old);
+	g_object_set (new, NM_SETTING_CONNECTION_ID, "some different connection id", NULL);
+
+	/* First make sure they are different */
+	success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT);
+	g_assert (success == FALSE);
+
+	success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_IGNORE_ID);
+	g_assert (success);
+}
+
+static void
+test_setting_compare_secrets (NMSettingSecretFlags secret_flags,
+                              NMSettingCompareFlags comp_flags,
+                              gboolean remove_secret)
+{
+	NMSetting *old, *new;
+	gboolean success;
+
+	/* Make sure that a connection with transient/unsaved secrets compares
+	 * successfully to the same connection without those secrets.
+	 */
+
+	old = nm_setting_wireless_security_new ();
+	g_object_set (old,
+	              NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk",
+	              NM_SETTING_WIRELESS_SECURITY_PSK, "really cool psk",
+	              NULL);
+	nm_setting_set_secret_flags (old, NM_SETTING_WIRELESS_SECURITY_PSK, secret_flags, NULL);
+
+	/* Clear the PSK from the duplicated setting */
+	new = nm_setting_duplicate (old);
+	if (remove_secret) {
+		g_object_set (new, NM_SETTING_WIRELESS_SECURITY_PSK, NULL, NULL);
+
+		success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT);
+		g_assert (success == FALSE);
+	}
+
+	success = nm_setting_compare (old, new, comp_flags);
+	g_assert (success);
+}
+
+static void
+test_setting_compare_vpn_secrets (NMSettingSecretFlags secret_flags,
+                                  NMSettingCompareFlags comp_flags,
+                                  gboolean remove_secret)
+{
+	NMSetting *old, *new;
+	gboolean success;
+
+	/* Make sure that a connection with transient/unsaved secrets compares
+	 * successfully to the same connection without those secrets.
+	 */
+
+	old = nm_setting_vpn_new ();
+	nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "foobarbaz", "really secret password");
+	nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "asdfasdfasdf", "really adfasdfasdfasdf");
+	nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "0123456778", "abcdefghijklmnpqrstuvqxyz");
+	nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "borkbork", "yet another really secret password");
+	nm_setting_set_secret_flags (old, "borkbork", secret_flags, NULL);
+
+	/* Clear "borkbork" from the duplicated setting */
+	new = nm_setting_duplicate (old);
+	if (remove_secret) {
+		nm_setting_vpn_remove_secret (NM_SETTING_VPN (new), "borkbork");
+
+		/* First make sure they are different */
+		success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT);
+		g_assert (success == FALSE);
+	}
+
+	success = nm_setting_compare (old, new, comp_flags);
+	g_assert (success);
+}
+
 int main (int argc, char **argv)
 {
 	GError *error = NULL;
-	DBusGConnection *bus;
 	char *base;
 
 	g_type_init ();
-	bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
 
 	if (!nm_utils_init (&error))
 		FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message);
@@ -1228,6 +1316,16 @@ int main (int argc, char **argv)
 	test_setting_to_hash_all ();
 	test_setting_to_hash_no_secrets ();
 	test_setting_to_hash_only_secrets ();
+	test_setting_compare_id ();
+	test_setting_compare_secrets (NM_SETTING_SECRET_FLAG_AGENT_OWNED, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, TRUE);
+	test_setting_compare_secrets (NM_SETTING_SECRET_FLAG_NOT_SAVED, NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS, TRUE);
+	test_setting_compare_secrets (NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, TRUE);
+	test_setting_compare_secrets (NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_EXACT, FALSE);
+	test_setting_compare_vpn_secrets (NM_SETTING_SECRET_FLAG_AGENT_OWNED, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, TRUE);
+	test_setting_compare_vpn_secrets (NM_SETTING_SECRET_FLAG_NOT_SAVED, NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS, TRUE);
+	test_setting_compare_vpn_secrets (NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, TRUE);
+	test_setting_compare_vpn_secrets (NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_EXACT, FALSE);
+
 	test_connection_to_hash_setting_name ();
 	test_setting_connection_permissions_helpers ();
 	test_setting_connection_permissions_property ();
diff --git a/libnm-util/tests/test-secrets.c b/libnm-util/tests/test-secrets.c
index 6d46f99e..1fe3c438 100644
--- a/libnm-util/tests/test-secrets.c
+++ b/libnm-util/tests/test-secrets.c
@@ -20,7 +20,6 @@
  */
 
 #include <glib.h>
-#include <dbus/dbus-glib.h>
 #include <string.h>
 
 #include "nm-test-helpers.h"
@@ -592,7 +591,84 @@ test_update_secrets_wifi_bad_setting_name (void)
 	                                        "asdfasdfasdfasf",
 	                                        secrets,
 	                                        &error);
-	g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND);
+	g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND);
+	g_assert (success == FALSE);
+
+	g_object_unref (connection);
+}
+
+static void
+test_update_secrets_whole_connection (void)
+{
+	NMConnection *connection;
+	NMSettingWirelessSecurity *s_wsec;
+	GHashTable *secrets, *wsec_hash;
+	GError *error = NULL;
+	gboolean success;
+	const char *wepkey = "11111111111111111111111111";
+
+	connection = wifi_connection_new ();
+
+	/* Build up the secrets hash */
+	secrets = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL);
+	wsec_hash = g_hash_table_lookup (secrets, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+	g_assert (wsec_hash);
+	g_hash_table_insert (wsec_hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey));
+
+	success = nm_connection_update_secrets (connection, NULL, secrets, &error);
+	g_assert_no_error (error);
+	g_assert (success == TRUE);
+
+	s_wsec = nm_connection_get_setting_wireless_security (connection);
+	g_assert (s_wsec);
+	g_assert_cmpstr (nm_setting_wireless_security_get_wep_key (s_wsec, 0), ==, wepkey);
+
+	g_object_unref (connection);
+}
+
+static void
+test_update_secrets_whole_connection_empty_hash (void)
+{
+	NMConnection *connection;
+	GHashTable *secrets;
+	GError *error = NULL;
+	gboolean success;
+
+	connection = wifi_connection_new ();
+	secrets = g_hash_table_new (g_str_hash, g_str_equal);
+	success = nm_connection_update_secrets (connection, NULL, secrets, &error);
+	g_assert_no_error (error);
+	g_assert (success == TRUE);
+	g_object_unref (connection);
+}
+
+static void
+test_update_secrets_whole_connection_bad_setting (void)
+{
+	NMConnection *connection;
+	GHashTable *secrets, *wsec_hash;
+	GError *error = NULL;
+	gboolean success;
+	const char *wepkey = "11111111111111111111111111";
+
+	connection = wifi_connection_new ();
+
+	/* Build up the secrets hash */
+	secrets = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL);
+	wsec_hash = g_hash_table_lookup (secrets, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+	g_assert (wsec_hash);
+	g_hash_table_insert (wsec_hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey));
+
+	/* Steal the wsec setting hash so it's not deallocated, and stuff it back
+	 * in with a different name so we ensure libnm-util is returning the right
+	 * error when it finds an entry in the connection hash that doesn't match
+	 * any setting in the connection.
+	 */
+	g_hash_table_steal (secrets, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+	g_hash_table_insert (secrets, "asdfasdfasdfasdf", wsec_hash);
+
+	success = nm_connection_update_secrets (connection, NULL, secrets, &error);
+	g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND);
 	g_assert (success == FALSE);
 
 	g_object_unref (connection);
@@ -601,11 +677,9 @@ test_update_secrets_wifi_bad_setting_name (void)
 int main (int argc, char **argv)
 {
 	GError *error = NULL;
-	DBusGConnection *bus;
 	char *base;
 
 	g_type_init ();
-	bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
 
 	if (!nm_utils_init (&error))
 		FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message);
@@ -620,6 +694,10 @@ int main (int argc, char **argv)
 	test_update_secrets_wifi_full_hash ();
 	test_update_secrets_wifi_bad_setting_name ();
 
+	test_update_secrets_whole_connection ();
+	test_update_secrets_whole_connection_empty_hash ();
+	test_update_secrets_whole_connection_bad_setting ();
+
 	base = g_path_get_basename (argv[0]);
 	fprintf (stdout, "%s: SUCCESS\n", base);
 	g_free (base);
diff --git a/libnm-util/tests/test-setting-8021x.c b/libnm-util/tests/test-setting-8021x.c
index 6d1e3bd0..bdfc8e03 100644
--- a/libnm-util/tests/test-setting-8021x.c
+++ b/libnm-util/tests/test-setting-8021x.c
@@ -20,7 +20,6 @@
  */
 
 #include <glib.h>
-#include <dbus/dbus-glib.h>
 #include <string.h>
 
 #include "nm-test-helpers.h"
@@ -407,14 +406,12 @@ test_clear_phase2_private_key (const char *path, const char *password)
 int main (int argc, char **argv)
 {
 	GError *error = NULL;
-	DBusGConnection *bus;
 	char *base;
 
 	if (argc < 3)
 		FAIL ("init", "need at least two arguments: <path> <password>");
 
 	g_type_init ();
-	bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
 
 	if (!nm_utils_init (&error))
 		FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message);
diff --git a/libnm-util/tests/test-settings-defaults.c b/libnm-util/tests/test-settings-defaults.c
index 9f38a145..b77ddfef 100644
--- a/libnm-util/tests/test-settings-defaults.c
+++ b/libnm-util/tests/test-settings-defaults.c
@@ -15,12 +15,11 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Copyright (C) 2008 Red Hat, Inc.
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
  *
  */
 
 #include <glib.h>
-#include <dbus/dbus-glib.h>
 #include <string.h>
 
 #include "nm-test-helpers.h"
@@ -103,11 +102,9 @@ test_defaults (GType type, const char *name)
 int main (int argc, char **argv)
 {
 	GError *error = NULL;
-	DBusGConnection *bus;
 	char *base;
 
 	g_type_init ();
-	bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
 
 	if (!nm_utils_init (&error))
 		FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message);