about summary refs log tree commit diff
path: root/cli/src
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2011-10-28 23:04:16 +0200
committerMichael Biebl <biebl@debian.org>2011-10-28 23:04:16 +0200
commit485d149fe80915d94ed49ea6c2c0552cf7a3e79a (patch)
tree6a48492b46b8c1e3df1c58626c28f05a978c61f7 /cli/src
parent263bf4c0c89bb88dc995acd9a6a2de9095fbd461 (diff)
Imported Upstream version 0.9.1.95 upstream/0.9.1.95
Diffstat (limited to 'cli/src')
-rw-r--r--cli/src/Makefile.in8
-rw-r--r--cli/src/connections.c107
-rw-r--r--cli/src/devices.c67
-rw-r--r--cli/src/network-manager.c9
-rw-r--r--cli/src/settings.c221
-rw-r--r--cli/src/utils.c3
6 files changed, 286 insertions, 129 deletions
diff --git a/cli/src/Makefile.in b/cli/src/Makefile.in
index 33aa3f2b..11c1d50c 100644
--- a/cli/src/Makefile.in
+++ b/cli/src/Makefile.in
@@ -189,8 +189,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
+LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
+LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
diff --git a/cli/src/connections.c b/cli/src/connections.c
index 5febc58a..7d4fffc0 100644
--- a/cli/src/connections.c
+++ b/cli/src/connections.c
@@ -141,39 +141,26 @@ typedef struct {
 	char **argv;
 } ArgsInfo;
 
-extern GMainLoop *loop;   /* glib main loop variable */
+/* glib main loop variable - defined in nmcli.c */
+extern GMainLoop *loop;
 
 static ArgsInfo args_info;
 
-/* static function prototypes */
-static void usage (void);
-static void quit (void);
-static void show_connection (NMConnection *data, gpointer user_data);
-static NMConnection *find_connection (GSList *list, const char *filter_type, const char *filter_val);
-static gboolean find_device_for_connection (NmCli *nmc, NMConnection *connection, const char *iface, const char *ap,
-                                            const char *nsp, NMDevice **device, const char **spec_object, GError **error);
-static const char *active_connection_state_to_string (NMActiveConnectionState state);
-static void active_connection_state_cb (NMActiveConnection *active, GParamSpec *pspec, gpointer user_data);
-static void get_connections_cb (NMRemoteSettings *settings, gpointer user_data);
-static NMCResultCode do_connections_list (NmCli *nmc, int argc, char **argv);
-static NMCResultCode do_connections_status (NmCli *nmc, int argc, char **argv);
-static NMCResultCode do_connection_up (NmCli *nmc, int argc, char **argv);
-static NMCResultCode do_connection_down (NmCli *nmc, int argc, char **argv);
-
 static void
 usage (void)
 {
 	fprintf (stderr,
 	         _("Usage: nmcli con { COMMAND | help }\n"
-	         "  COMMAND := { list | status | up | down }\n\n"
+	         "  COMMAND := { list | status | up | down | delete }\n\n"
 	         "  list [id <id> | uuid <id>]\n"
 	         "  status\n"
 #if WITH_WIMAX
-	         "  up id <id> | uuid <id> [iface <iface>] [ap <hwaddr>] [nsp <name>] [--nowait] [--timeout <timeout>]\n"
+	         "  up id <id> | uuid <id> [iface <iface>] [ap <BSSID>] [nsp <name>] [--nowait] [--timeout <timeout>]\n"
 #else
-	         "  up id <id> | uuid <id> [iface <iface>] [ap <hwaddr>] [--nowait] [--timeout <timeout>]\n"
+	         "  up id <id> | uuid <id> [iface <iface>] [ap <BSSID>] [--nowait] [--timeout <timeout>]\n"
 #endif
-	         "  down id <id> | uuid <id>\n"));
+	         "  down id <id> | uuid <id>\n"
+	         "  delete id <id> | uuid <id>\n"));
 }
 
 /* The real commands that do something - i.e. not 'help', etc. */
@@ -182,6 +169,7 @@ static const char *real_con_commands[] = {
 	"status",
 	"up",
 	"down",
+	"delete",
 	NULL
 };
 
@@ -1073,7 +1061,7 @@ find_device_for_connection (NmCli *nmc,
 	g_assert (s_con);
 	con_type = nm_setting_connection_get_connection_type (s_con);
 
-	if (strcmp (con_type, "vpn") == 0) {
+	if (strcmp (con_type, NM_SETTING_VPN_SETTING_NAME) == 0) {
 		/* VPN connections */
 		NMActiveConnection *active = NULL;
 		if (iface) {
@@ -1116,22 +1104,22 @@ find_device_for_connection (NmCli *nmc,
 				}
 			}
 
-			if (found_device && ap && !strcmp (con_type, "802-11-wireless") && NM_IS_DEVICE_WIFI (dev)) {
-				char *hwaddr_up = g_ascii_strup (ap, -1);
+			if (found_device && ap && !strcmp (con_type, NM_SETTING_WIRELESS_SETTING_NAME) && NM_IS_DEVICE_WIFI (dev)) {
+				char *bssid_up = g_ascii_strup (ap, -1);
 				const GPtrArray *aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (dev));
 				found_device = NULL;  /* Mark as not found; set to the device again later, only if AP matches */
 
 				for (j = 0; aps && (j < aps->len); j++) {
 					NMAccessPoint *candidate_ap = g_ptr_array_index (aps, j);
-					const char *candidate_hwaddr = nm_access_point_get_hw_address (candidate_ap);
+					const char *candidate_bssid = nm_access_point_get_bssid (candidate_ap);
 
-					if (!strcmp (hwaddr_up, candidate_hwaddr)) {
+					if (!strcmp (bssid_up, candidate_bssid)) {
 						found_device = dev;
 						*spec_object = nm_object_get_path (NM_OBJECT (candidate_ap));
 						break;
 					}
 				}
-				g_free (hwaddr_up);
+				g_free (bssid_up);
 			}
 
 #if WITH_WIMAX
@@ -1576,6 +1564,66 @@ error:
 }
 
 static NMCResultCode
+do_connection_delete (NmCli *nmc, int argc, char **argv)
+{
+	NMConnection *connection = NULL;
+	const char *selector = NULL;
+	const char *id = NULL;
+	GError *error = NULL;
+
+	nmc->should_wait = FALSE;
+
+	while (argc > 0) {
+		if (strcmp (*argv, "id") == 0 || strcmp (*argv, "uuid") == 0) {
+			selector = *argv;
+			if (next_arg (&argc, &argv) != 0) {
+				g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
+				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+				goto error;
+			}
+			id = *argv;
+		}
+		else
+			fprintf (stderr, _("Unknown parameter: %s\n"), *argv);
+
+		argc--;
+		argv++;
+	}
+
+	if (!id) {
+		g_string_printf (nmc->return_text, _("Error: id or uuid has to be specified."));
+		nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
+		goto error;
+	}
+
+	if (!nmc_is_nm_running (nmc, &error)) {
+		if (error) {
+			g_string_printf (nmc->return_text, _("Error: Can't find out if NetworkManager is running: %s."), error->message);
+			nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+			g_error_free (error);
+		} else {
+			g_string_printf (nmc->return_text, _("Error: NetworkManager is not running."));
+			nmc->return_value = NMC_RESULT_ERROR_NM_NOT_RUNNING;
+		}
+		goto error;
+	}
+
+	connection = find_connection (nmc->system_connections, selector, id);
+
+	if (!connection) {
+		g_string_printf (nmc->return_text, _("Error: Unknown connection: %s."), id);
+		nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+		goto error;
+	}
+
+	/* Delete the connection */
+	nm_remote_connection_delete (NM_REMOTE_CONNECTION (connection), NULL, NULL);
+
+error:
+	return nmc->return_value;
+}
+
+static NMCResultCode
 parse_cmd (NmCli *nmc, int argc, char **argv)
 {
 	GError *error = NULL;
@@ -1600,6 +1648,9 @@ parse_cmd (NmCli *nmc, int argc, char **argv)
 		else if (matches(*argv, "down") == 0) {
 			nmc->return_value = do_connection_down (nmc, argc-1, argv+1);
 		}
+		else if (matches(*argv, "delete") == 0) {
+			nmc->return_value = do_connection_delete (nmc, argc-1, argv+1);
+		}
 		else if (matches (*argv, "help") == 0) {
 			usage ();
 			nmc->should_wait = FALSE;
@@ -1672,6 +1723,7 @@ do_connections (NmCli *nmc, int argc, char **argv)
 		if (error || !bus) {
 			g_string_printf (nmc->return_text, _("Error: could not connect to D-Bus."));
 			nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+			nmc->should_wait = FALSE;
 			return nmc->return_value;
 		}
 
@@ -1679,8 +1731,8 @@ do_connections (NmCli *nmc, int argc, char **argv)
 		if (!(nmc->system_settings = nm_remote_settings_new (bus))) {
 			g_string_printf (nmc->return_text, _("Error: Could not get system settings."));
 			nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+			nmc->should_wait = FALSE;
 			return nmc->return_value;
-
 		}
 
 		/* find out whether settings service is running */
@@ -1689,6 +1741,7 @@ do_connections (NmCli *nmc, int argc, char **argv)
 		if (!nmc->system_settings_running) {
 			g_string_printf (nmc->return_text, _("Error: Can't obtain connections: settings service is not running."));
 			nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
+			nmc->should_wait = FALSE;
 			return nmc->return_value;
 		}
 
diff --git a/cli/src/devices.c b/cli/src/devices.c
index c6228ba1..500d2341 100644
--- a/cli/src/devices.c
+++ b/cli/src/devices.c
@@ -236,18 +236,8 @@ static NmcOutputField nmc_fields_dev_wimax_list[] = {
 #endif
 
 
-/* static function prototypes */
-static void usage (void);
-static const char *device_state_to_string (NMDeviceState state);
-static NMCResultCode do_devices_status (NmCli *nmc, int argc, char **argv);
-static NMCResultCode do_devices_list (NmCli *nmc, int argc, char **argv);
-static NMCResultCode do_device_disconnect (NmCli *nmc, int argc, char **argv);
-static NMCResultCode do_device_wifi (NmCli *nmc, int argc, char **argv);
-#if WITH_WIMAX
-static NMCResultCode do_device_wimax (NmCli *nmc, int argc, char **argv);
-#endif
-
-extern GMainLoop *loop;   /* glib main loop variable */
+/* glib main loop variable - defined in nmcli.c */
+extern GMainLoop *loop;
 
 static void
 usage (void)
@@ -262,7 +252,7 @@ usage (void)
 	         "  status\n"
 	         "  list [iface <iface>]\n"
 	         "  disconnect iface <iface> [--nowait] [--timeout <timeout>]\n"
-	         "  wifi [list [iface <iface>] [hwaddr <hwaddr>]]\n"
+	         "  wifi [list [iface <iface>] [bssid <BSSID>]]\n"
 #if WITH_WIMAX
 	         "  wimax [list [iface <iface>] [nsp <name>]]\n\n"
 #endif
@@ -441,15 +431,15 @@ detail_access_point (gpointer data, gpointer user_data)
 	NM80211ApSecurityFlags wpa_flags, rsn_flags;
 	guint32 freq, bitrate;
 	guint8 strength;
-	const GByteArray *ssid; 
-	const char *hwaddr;
+	const GByteArray *ssid;
+	const char *bssid;
 	NM80211Mode mode;
 	char *freq_str, *ssid_str, *bitrate_str, *strength_str, *wpa_flags_str, *rsn_flags_str;
 	GString *security_str;
 	char *ap_name;
 
 	if (info->active_bssid) {
-		const char *current_bssid = nm_access_point_get_hw_address (ap);
+		const char *current_bssid = nm_access_point_get_bssid (ap);
 		if (current_bssid && !strcmp (current_bssid, info->active_bssid))
 			active = TRUE;
 	}
@@ -459,7 +449,7 @@ detail_access_point (gpointer data, gpointer user_data)
 	wpa_flags = nm_access_point_get_wpa_flags (ap);
 	rsn_flags = nm_access_point_get_rsn_flags (ap);
 	ssid = nm_access_point_get_ssid (ap);
-	hwaddr = nm_access_point_get_hw_address (ap);
+	bssid = nm_access_point_get_bssid (ap);
 	freq = nm_access_point_get_frequency (ap);
 	mode = nm_access_point_get_mode (ap);
 	bitrate = nm_access_point_get_max_bitrate (ap);
@@ -497,7 +487,7 @@ detail_access_point (gpointer data, gpointer user_data)
 	ap_name = g_strdup_printf ("AP%d", info->index++); /* AP */
 	info->nmc->allowed_fields[0].value = ap_name;
 	info->nmc->allowed_fields[1].value = ssid_str;
-	info->nmc->allowed_fields[2].value = hwaddr;
+	info->nmc->allowed_fields[2].value = bssid;
 	info->nmc->allowed_fields[3].value = mode == NM_802_11_MODE_ADHOC ? _("Ad-Hoc") : mode == NM_802_11_MODE_INFRA ? _("Infrastructure") : _("Unknown");
 	info->nmc->allowed_fields[4].value = freq_str;
 	info->nmc->allowed_fields[5].value = bitrate_str;
@@ -725,7 +715,7 @@ show_device_info (gpointer data, gpointer user_data)
 			if (!strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[3].name)) {
 				if (state == NM_DEVICE_STATE_ACTIVATED) {
 					active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device));
-					active_bssid = active_ap ? nm_access_point_get_hw_address (active_ap) : NULL;
+					active_bssid = active_ap ? nm_access_point_get_bssid (active_ap) : NULL;
 				}
 
 				nmc->allowed_fields = nmc_fields_dev_wifi_list;
@@ -1275,7 +1265,7 @@ show_acces_point_info (NMDevice *device, NmCli *nmc)
 
 	if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) {
 		active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device));
-		active_bssid = active_ap ? nm_access_point_get_hw_address (active_ap) : NULL;
+		active_bssid = active_ap ? nm_access_point_get_bssid (active_ap) : NULL;
 	}
 
 	info = g_malloc0 (sizeof (APInfo));
@@ -1296,7 +1286,7 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
 	NMDevice *device = NULL;
 	NMAccessPoint *ap = NULL;
 	const char *iface = NULL;
-	const char *hwaddr_user = NULL;
+	const char *bssid_user = NULL;
 	const GPtrArray *devices;
 	const GPtrArray *aps;
 	APInfo *info;
@@ -1316,13 +1306,14 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
 				goto error;
 			}
 			iface = *argv;
-		} else if (strcmp (*argv, "hwaddr") == 0) {
+		} else if (strcmp (*argv, "bssid") == 0 || strcmp (*argv, "hwaddr") == 0) {
+			/* hwaddr is deprecated and will be removed later */
 			if (next_arg (&argc, &argv) != 0) {
 				g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv);
 				nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
 				goto error;
 			}
-			hwaddr_user = *argv;
+			bssid_user = *argv;
 		} else {
 			fprintf (stderr, _("Unknown parameter: %s\n"), *argv);
 		}
@@ -1392,21 +1383,21 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
 		}
 
 		if (NM_IS_DEVICE_WIFI (device)) {
-			if (hwaddr_user) {
+			if (bssid_user) {
 				/* Specific AP requested - list only that */
 				aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (device));
 				for (j = 0; aps && (j < aps->len); j++) {
-					char *hwaddr_up;
+					char *bssid_up;
 					NMAccessPoint *candidate_ap = g_ptr_array_index (aps, j);
-					const char *candidate_hwaddr = nm_access_point_get_hw_address (candidate_ap);
+					const char *candidate_bssid = nm_access_point_get_bssid (candidate_ap);
 
-					hwaddr_up = g_ascii_strup (hwaddr_user, -1);
-					if (!strcmp (hwaddr_up, candidate_hwaddr))
+					bssid_up = g_ascii_strup (bssid_user, -1);
+					if (!strcmp (bssid_up, candidate_bssid))
 						ap = candidate_ap;
-					g_free (hwaddr_up);
+					g_free (bssid_up);
 				}
 				if (!ap) {
-				 	g_string_printf (nmc->return_text, _("Error: Access point with hwaddr '%s' not found."), hwaddr_user);
+				 	g_string_printf (nmc->return_text, _("Error: Access point with bssid '%s' not found."), bssid_user);
 					nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
 					goto error;
 				}
@@ -1430,7 +1421,7 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
 	} else {
 		/* List APs for all devices */
 		print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */
-		if (hwaddr_user) {
+		if (bssid_user) {
 			/* Specific AP requested - list only that */
 			for (i = 0; devices && (i < devices->len); i++) {
 				NMDevice *dev = g_ptr_array_index (devices, i);
@@ -1440,12 +1431,12 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
 
 				aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (dev));
 				for (j = 0; aps && (j < aps->len); j++) {
-					char *hwaddr_up;
+					char *bssid_up;
 					NMAccessPoint *candidate_ap = g_ptr_array_index (aps, j);
-					const char *candidate_hwaddr = nm_access_point_get_hw_address (candidate_ap);
+					const char *candidate_bssid = nm_access_point_get_bssid (candidate_ap);
 
-					hwaddr_up = g_ascii_strup (hwaddr_user, -1);
-					if (!strcmp (hwaddr_up, candidate_hwaddr)) {
+					bssid_up = g_ascii_strup (bssid_user, -1);
+					if (!strcmp (bssid_up, candidate_bssid)) {
 						ap = candidate_ap;
 
 						info = g_malloc0 (sizeof (APInfo));
@@ -1456,11 +1447,11 @@ do_device_wifi_list (NmCli *nmc, int argc, char **argv)
 						detail_access_point (ap, info);
 						g_free (info);
 					}
-					g_free (hwaddr_up);
+					g_free (bssid_up);
 				}
 			}
 			if (!ap) {
-			 	g_string_printf (nmc->return_text, _("Error: Access point with hwaddr '%s' not found."), hwaddr_user);
+			 	g_string_printf (nmc->return_text, _("Error: Access point with bssid '%s' not found."), bssid_user);
 				nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
 				goto error;
 			}
@@ -1667,7 +1658,7 @@ do_device_wimax_list (NmCli *nmc, int argc, char **argv)
 				}
 			}
 			if (!nsp) {
-			 	g_string_printf (nmc->return_text, _("Error: Access point with hwaddr '%s' not found."), nsp_user);
+			 	g_string_printf (nmc->return_text, _("Error: Access point with nsp '%s' not found."), nsp_user);
 				nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
 				goto error;
 			}
diff --git a/cli/src/network-manager.c b/cli/src/network-manager.c
index ac9a3841..c23c9fae 100644
--- a/cli/src/network-manager.c
+++ b/cli/src/network-manager.c
@@ -57,16 +57,9 @@ static NmcOutputField nmc_fields_nm_status[] = {
 #define NMC_FIELDS_NM_WWAN           "WWAN"
 #define NMC_FIELDS_NM_WIMAX          "WIMAX"
 
-
+/* glib main loop variable - defined in nmcli.c */
 extern GMainLoop *loop;
 
-/* static function prototypes */
-static void usage (void);
-static void quit (void);
-static const char *nm_state_to_string (NMState state);
-static NMCResultCode show_nm_status (NmCli *nmc);
-
-
 static void
 usage (void)
 {
diff --git a/cli/src/settings.c b/cli/src/settings.c
index c2385370..ccbe9589 100644
--- a/cli/src/settings.c
+++ b/cli/src/settings.c
@@ -14,7 +14,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * (C) Copyright 2010 Red Hat, Inc.
+ * (C) Copyright 2010 - 2011 Red Hat, Inc.
  */
 
 #include "config.h"
@@ -39,6 +39,7 @@ static NmcOutputField nmc_fields_setting_connection[] = {
 	SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT, 13),  /* 4 */
 	SETTING_FIELD (NM_SETTING_CONNECTION_TIMESTAMP, 10),    /* 5 */
 	SETTING_FIELD (NM_SETTING_CONNECTION_READ_ONLY, 10),    /* 6 */
+	SETTING_FIELD (NM_SETTING_CONNECTION_PERMISSIONS, 30),  /* 7 */
 	{NULL, NULL, 0, NULL, 0}
 };
 #define NMC_FIELDS_SETTING_CONNECTION_ALL     "name"","\
@@ -47,19 +48,24 @@ static NmcOutputField nmc_fields_setting_connection[] = {
                                               NM_SETTING_CONNECTION_TYPE","\
                                               NM_SETTING_CONNECTION_AUTOCONNECT","\
                                               NM_SETTING_CONNECTION_TIMESTAMP","\
-                                              NM_SETTING_CONNECTION_READ_ONLY
+                                              NM_SETTING_CONNECTION_READ_ONLY","\
+                                              NM_SETTING_CONNECTION_PERMISSIONS
 #define NMC_FIELDS_SETTING_CONNECTION_COMMON  NMC_FIELDS_SETTING_CONNECTION_ALL
 
 /* Available fields for NM_SETTING_WIRED_SETTING_NAME */
 static NmcOutputField nmc_fields_setting_wired[] = {
-	SETTING_FIELD ("name",  17),                             /* 0 */
-	SETTING_FIELD (NM_SETTING_WIRED_PORT, 8),                /* 1 */
-	SETTING_FIELD (NM_SETTING_WIRED_SPEED, 10),              /* 2 */
-	SETTING_FIELD (NM_SETTING_WIRED_DUPLEX, 10),             /* 3 */
-	SETTING_FIELD (NM_SETTING_WIRED_AUTO_NEGOTIATE, 15),     /* 4 */
-	SETTING_FIELD (NM_SETTING_WIRED_MAC_ADDRESS, 19),        /* 5 */
-	SETTING_FIELD (NM_SETTING_WIRED_CLONED_MAC_ADDRESS, 19), /* 6 */
-	SETTING_FIELD (NM_SETTING_WIRED_MTU, 6),                 /* 7 */
+	SETTING_FIELD ("name",  17),                                  /* 0 */
+	SETTING_FIELD (NM_SETTING_WIRED_PORT, 8),                     /* 1 */
+	SETTING_FIELD (NM_SETTING_WIRED_SPEED, 10),                   /* 2 */
+	SETTING_FIELD (NM_SETTING_WIRED_DUPLEX, 10),                  /* 3 */
+	SETTING_FIELD (NM_SETTING_WIRED_AUTO_NEGOTIATE, 15),          /* 4 */
+	SETTING_FIELD (NM_SETTING_WIRED_MAC_ADDRESS, 19),             /* 5 */
+	SETTING_FIELD (NM_SETTING_WIRED_CLONED_MAC_ADDRESS, 19),      /* 6 */
+	SETTING_FIELD (NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, 39),   /* 7 */
+	SETTING_FIELD (NM_SETTING_WIRED_MTU, 6),                      /* 8 */
+	SETTING_FIELD (NM_SETTING_WIRED_S390_SUBCHANNELS, 20),        /* 9 */
+	SETTING_FIELD (NM_SETTING_WIRED_S390_NETTYPE, 15),            /* 10 */
+	SETTING_FIELD (NM_SETTING_WIRED_S390_OPTIONS, 20),            /* 11 */
 	{NULL, NULL, 0, NULL, 0}
 };
 #define NMC_FIELDS_SETTING_WIRED_ALL     "name"","\
@@ -69,7 +75,11 @@ static NmcOutputField nmc_fields_setting_wired[] = {
                                          NM_SETTING_WIRED_AUTO_NEGOTIATE","\
                                          NM_SETTING_WIRED_MAC_ADDRESS","\
                                          NM_SETTING_WIRED_CLONED_MAC_ADDRESS","\
-                                         NM_SETTING_WIRED_MTU
+                                         NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST","\
+                                         NM_SETTING_WIRED_MTU","\
+                                         NM_SETTING_WIRED_S390_SUBCHANNELS","\
+                                         NM_SETTING_WIRED_S390_NETTYPE","\
+                                         NM_SETTING_WIRED_S390_OPTIONS
 #define NMC_FIELDS_SETTING_WIRED_COMMON  NMC_FIELDS_SETTING_WIRED_ALL
 
 /* Available fields for NM_SETTING_802_1X_SETTING_NAME */
@@ -80,22 +90,26 @@ static NmcOutputField nmc_fields_setting_8021X[] = {
 	SETTING_FIELD (NM_SETTING_802_1X_ANONYMOUS_IDENTITY, 15),           /* 3 */
 	SETTING_FIELD (NM_SETTING_802_1X_CA_CERT, 10),                      /* 4 */
 	SETTING_FIELD (NM_SETTING_802_1X_CA_PATH, 10),                      /* 5 */
-	SETTING_FIELD (NM_SETTING_802_1X_CLIENT_CERT, 10),                  /* 6 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE1_PEAPVER, 10),               /* 7 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE1_PEAPLABEL, 10),             /* 8 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, 10),     /* 9 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTH, 10),                  /* 10 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTHEAP, 10),               /* 11 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_CERT, 20),               /* 12 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_PATH, 20),               /* 13 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CLIENT_CERT, 20),           /* 14 */
-	SETTING_FIELD (NM_SETTING_802_1X_PASSWORD, 10),                     /* 15 */
-	SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY, 15),                  /* 16 */
-	SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, 20),         /* 17 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, 20),           /* 18 */
-	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, 20),  /* 19 */
-	SETTING_FIELD (NM_SETTING_802_1X_PIN, 8),                           /* 20 */
-	SETTING_FIELD (NM_SETTING_802_1X_SYSTEM_CA_CERTS, 17),              /* 21 */
+	SETTING_FIELD (NM_SETTING_802_1X_SUBJECT_MATCH, 10),                /* 6 */
+	SETTING_FIELD (NM_SETTING_802_1X_ALTSUBJECT_MATCHES, 10),           /* 7 */
+	SETTING_FIELD (NM_SETTING_802_1X_CLIENT_CERT, 10),                  /* 8 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE1_PEAPVER, 10),               /* 9 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE1_PEAPLABEL, 10),             /* 10 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, 10),     /* 11 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTH, 10),                  /* 12 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_AUTHEAP, 10),               /* 13 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_CERT, 20),               /* 14 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CA_PATH, 20),               /* 15 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH, 10),         /* 16 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES, 10),    /* 17 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_CLIENT_CERT, 20),           /* 18 */
+	SETTING_FIELD (NM_SETTING_802_1X_PASSWORD, 10),                     /* 19 */
+	SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY, 15),                  /* 20 */
+	SETTING_FIELD (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, 20),         /* 21 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, 20),           /* 22 */
+	SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, 20),  /* 23 */
+	SETTING_FIELD (NM_SETTING_802_1X_PIN, 8),                           /* 24 */
+	SETTING_FIELD (NM_SETTING_802_1X_SYSTEM_CA_CERTS, 17),              /* 25 */
 	{NULL, NULL, 0, NULL, 0}
 };
 #define NMC_FIELDS_SETTING_802_1X_ALL     "name"","\
@@ -104,6 +118,8 @@ static NmcOutputField nmc_fields_setting_8021X[] = {
                                           NM_SETTING_802_1X_ANONYMOUS_IDENTITY","\
                                           NM_SETTING_802_1X_CA_CERT","\
                                           NM_SETTING_802_1X_CA_PATH","\
+                                          NM_SETTING_802_1X_SUBJECT_MATCH","\
+                                          NM_SETTING_802_1X_ALTSUBJECT_MATCHES","\
                                           NM_SETTING_802_1X_CLIENT_CERT","\
                                           NM_SETTING_802_1X_PHASE1_PEAPVER","\
                                           NM_SETTING_802_1X_PHASE1_PEAPLABEL","\
@@ -112,6 +128,8 @@ static NmcOutputField nmc_fields_setting_8021X[] = {
                                           NM_SETTING_802_1X_PHASE2_AUTHEAP","\
                                           NM_SETTING_802_1X_PHASE2_CA_CERT","\
                                           NM_SETTING_802_1X_PHASE2_CA_PATH","\
+                                          NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH","\
+                                          NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES","\
                                           NM_SETTING_802_1X_PHASE2_CLIENT_CERT","\
                                           NM_SETTING_802_1X_PASSWORD","\
                                           NM_SETTING_802_1X_PRIVATE_KEY","\
@@ -134,9 +152,10 @@ static NmcOutputField nmc_fields_setting_wireless[] = {
 	SETTING_FIELD (NM_SETTING_WIRELESS_TX_POWER, 10),                  /* 7 */
 	SETTING_FIELD (NM_SETTING_WIRELESS_MAC_ADDRESS, 19),               /* 8 */
 	SETTING_FIELD (NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, 19),        /* 9 */
-	SETTING_FIELD (NM_SETTING_WIRELESS_MTU, 6),                        /* 10 */
-	SETTING_FIELD (NM_SETTING_WIRELESS_SEEN_BSSIDS, 35),               /* 11 */
-	SETTING_FIELD (NM_SETTING_WIRELESS_SEC, 10),                       /* 12 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST, 39),     /* 10 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_MTU, 6),                        /* 11 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SEEN_BSSIDS, 35),               /* 12 */
+	SETTING_FIELD (NM_SETTING_WIRELESS_SEC, 10),                       /* 13 */
 	{NULL, NULL, 0, NULL, 0}
 };
 #define NMC_FIELDS_SETTING_WIRELESS_ALL     "name"","\
@@ -149,6 +168,7 @@ static NmcOutputField nmc_fields_setting_wireless[] = {
                                             NM_SETTING_WIRELESS_TX_POWER","\
                                             NM_SETTING_WIRELESS_MAC_ADDRESS","\
                                             NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS","\
+                                            NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST","\
                                             NM_SETTING_WIRELESS_MTU","\
                                             NM_SETTING_WIRELESS_SEEN_BSSIDS","\
                                             NM_SETTING_WIRELESS_SEC
@@ -204,6 +224,7 @@ static NmcOutputField nmc_fields_setting_ip4_config[] = {
 	SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME, 19),      /* 9 */
 	SETTING_FIELD (NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, 14),           /* 10 */
 	SETTING_FIELD (NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, 15),           /* 11 */
+	SETTING_FIELD (NM_SETTING_IP4_CONFIG_MAY_FAIL, 12),                /* 12 */
 	{NULL, NULL, 0, NULL, 0}
 };
 #define NMC_FIELDS_SETTING_IP4_CONFIG_ALL     "name"","\
@@ -217,7 +238,8 @@ static NmcOutputField nmc_fields_setting_ip4_config[] = {
                                               NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID","\
                                               NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME","\
                                               NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME","\
-                                              NM_SETTING_IP4_CONFIG_NEVER_DEFAULT
+                                              NM_SETTING_IP4_CONFIG_NEVER_DEFAULT","\
+                                              NM_SETTING_IP4_CONFIG_MAY_FAIL
 #define NMC_FIELDS_SETTING_IP4_CONFIG_COMMON  NMC_FIELDS_SETTING_IP4_CONFIG_ALL
 
 /* Available fields for NM_SETTING_IP6_CONFIG_SETTING_NAME */
@@ -231,6 +253,7 @@ static NmcOutputField nmc_fields_setting_ip6_config[] = {
 	SETTING_FIELD (NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, 19),      /* 6 */
 	SETTING_FIELD (NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, 16),         /* 7 */
 	SETTING_FIELD (NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, 15),           /* 8 */
+	SETTING_FIELD (NM_SETTING_IP6_CONFIG_MAY_FAIL, 12),                /* 9 */
 	{NULL, NULL, 0, NULL, 0}
 };
 #define NMC_FIELDS_SETTING_IP6_CONFIG_ALL     "name"","\
@@ -241,7 +264,8 @@ static NmcOutputField nmc_fields_setting_ip6_config[] = {
                                               NM_SETTING_IP6_CONFIG_ROUTES","\
                                               NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES","\
                                               NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS","\
-                                              NM_SETTING_IP6_CONFIG_NEVER_DEFAULT
+                                              NM_SETTING_IP6_CONFIG_NEVER_DEFAULT","\
+                                              NM_SETTING_IP6_CONFIG_MAY_FAIL
 #define NMC_FIELDS_SETTING_IP6_CONFIG_COMMON  NMC_FIELDS_SETTING_IP4_CONFIG_ALL
 
 /* Available fields for NM_SETTING_SERIAL_SETTING_NAME */
@@ -480,6 +504,10 @@ allowed_bands_to_string (guint32 bands)
 		g_string_append (band_str, _("WCDMA 3GPP UMTS 900 MHz, "));
 	if (bands & NM_SETTING_GSM_BAND_U17IX)
 		g_string_append (band_str, _("WCDMA 3GPP UMTS 1700 MHz, "));
+	if (bands & NM_SETTING_GSM_BAND_U1900)
+		g_string_append (band_str, _("WCDMA 3GPP UMTS 1900 MHz, "));
+	if (bands & NM_SETTING_GSM_BAND_U2600)
+		g_string_append (band_str, _("WCDMA 3GPP UMTS 2600 MHz, "));
 
 	if (band_str->str[band_str->len-1] == '(')
 		g_string_assign (band_str, _("unknown"));
@@ -491,13 +519,16 @@ allowed_bands_to_string (guint32 bands)
 	return g_string_free (band_str, FALSE);
 }
 
-
 gboolean
 setting_connection_details (NMSetting *setting, NmCli *nmc)
 {
 	NMSettingConnection *s_con;
 	guint64 timestamp;
 	char *timestamp_str;
+	const char *perm_item;
+	const char *perm_type;
+	GString *perm = NULL;
+	int i;
 	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
 	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
 	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
@@ -513,6 +544,15 @@ setting_connection_details (NMSetting *setting, NmCli *nmc)
 	timestamp = nm_setting_connection_get_timestamp (s_con);
 	timestamp_str = g_strdup_printf ("%" G_GUINT64_FORMAT, timestamp);
 
+	/* get permissions */
+	perm = g_string_new (NULL);
+	for (i = 0; i < nm_setting_connection_get_num_permissions (s_con); i++) {
+		nm_setting_connection_get_permission (s_con, i, &perm_type, &perm_item, NULL);
+		g_string_append_printf (perm, "%s:%s,", perm_type, perm_item);
+	}
+	if (perm->len > 0)
+		g_string_truncate (perm, perm->len-1); /* remove trailing , */
+
 	nmc->allowed_fields[0].value = NM_SETTING_CONNECTION_SETTING_NAME;
 	nmc->allowed_fields[1].value = nm_setting_connection_get_id (s_con);
 	nmc->allowed_fields[2].value = nm_setting_connection_get_uuid (s_con);
@@ -520,11 +560,13 @@ setting_connection_details (NMSetting *setting, NmCli *nmc)
 	nmc->allowed_fields[4].value = nm_setting_connection_get_autoconnect (s_con) ? _("yes") : _("no");
 	nmc->allowed_fields[5].value = timestamp_str;
 	nmc->allowed_fields[6].value = nm_setting_connection_get_read_only (s_con) ? ("yes") : _("no");
+	nmc->allowed_fields[7].value = perm->str;
 
 	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
 	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
 
 	g_free (timestamp_str);
+	g_string_free (perm, TRUE);
 
 	return TRUE;
 }
@@ -534,7 +576,11 @@ setting_wired_details (NMSetting *setting, NmCli *nmc)
 {
 	NMSettingWired *s_wired;
 	const GByteArray *mac;
+	const GSList *iter;
+	const GPtrArray *s390_channels;
+	int i;
 	char *speed_str, *mtu_str, *device_mac_str = NULL, *cloned_mac_str = NULL;
+	GString *mac_blacklist_s, *s390_channels_s, *s390_options_s;
 	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
 	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
 	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
@@ -556,6 +602,29 @@ setting_wired_details (NMSetting *setting, NmCli *nmc)
 	if (mac)
 		cloned_mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);
 
+	mac_blacklist_s = g_string_new (NULL);
+	iter = nm_setting_wired_get_mac_address_blacklist (s_wired);
+	while (iter) {
+		g_string_append_printf (mac_blacklist_s, "%s,", (char *) iter->data);
+		iter = iter->next;
+	}
+	g_string_truncate (mac_blacklist_s, mac_blacklist_s->len-1);  /* chop off trailing ',' */
+
+	s390_channels_s = g_string_new (NULL);
+	s390_channels = nm_setting_wired_get_s390_subchannels (s_wired);
+	for (i = 0; s390_channels && i < s390_channels->len; i++)
+		g_string_append_printf (s390_channels_s, "%s,", (char *) g_ptr_array_index (s390_channels, i));
+	g_string_truncate (s390_channels_s, s390_channels_s->len-1);  /* chop off trailing ',' */
+
+	s390_options_s = g_string_new (NULL);
+	for (i = 0; i < nm_setting_wired_get_num_s390_options (s_wired); i++) {
+		const char *key, *value;
+
+		nm_setting_wired_get_s390_option (s_wired, i, &key, &value);
+		g_string_append_printf (s390_options_s, "%s=%s,", key, value);
+	}
+	g_string_truncate (s390_options_s, s390_options_s->len-1);  /* chop off trailing ',' */
+
 	nmc->allowed_fields[0].value = NM_SETTING_WIRED_SETTING_NAME;
 	nmc->allowed_fields[1].value = nm_setting_wired_get_port (s_wired);
 	nmc->allowed_fields[2].value = speed_str;
@@ -563,7 +632,11 @@ setting_wired_details (NMSetting *setting, NmCli *nmc)
 	nmc->allowed_fields[4].value = nm_setting_wired_get_auto_negotiate (s_wired) ? _("yes") : _("no");
 	nmc->allowed_fields[5].value = device_mac_str;
 	nmc->allowed_fields[6].value = cloned_mac_str;
-	nmc->allowed_fields[7].value = strcmp (mtu_str, "0") ? mtu_str : _("auto");
+	nmc->allowed_fields[7].value = mac_blacklist_s->str;
+	nmc->allowed_fields[8].value = strcmp (mtu_str, "0") ? mtu_str : _("auto");
+	nmc->allowed_fields[9].value = s390_channels_s->str;
+	nmc->allowed_fields[10].value = nm_setting_wired_get_s390_nettype (s_wired);
+	nmc->allowed_fields[11].value = s390_options_s->str;
 
 	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
 	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
@@ -572,6 +645,9 @@ setting_wired_details (NMSetting *setting, NmCli *nmc)
 	g_free (device_mac_str);
 	g_free (cloned_mac_str);
 	g_free (mtu_str);
+	g_string_free (mac_blacklist_s, TRUE);
+	g_string_free (s390_channels_s, TRUE);
+	g_string_free (s390_options_s, TRUE);
 
 	return TRUE;
 }
@@ -581,7 +657,7 @@ setting_802_1X_details (NMSetting *setting, NmCli *nmc)
 {
 	NMSetting8021x *s_8021X;
 	NMSetting8021xCKScheme scheme;
-	GString *eap_str;
+	GString *eap_str, *alt_sub_match, *phase2_alt_sub_match;
 	char *ca_cert_str = NULL, *client_cert_str = NULL, *phase2_ca_cert_str = NULL;
 	char *phase2_client_cert_str = NULL, *private_key_str = NULL, *phase2_private_key_str = NULL;
 	int i;
@@ -639,28 +715,42 @@ setting_802_1X_details (NMSetting *setting, NmCli *nmc)
 	if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
 		phase2_private_key_str = g_strdup (nm_setting_802_1x_get_phase2_private_key_path (s_8021X));
 
+	alt_sub_match = g_string_new (NULL);
+	for (i = 0; i < nm_setting_802_1x_get_num_altsubject_matches (s_8021X); i++)
+		g_string_append_printf (alt_sub_match, "%s,", nm_setting_802_1x_get_altsubject_match (s_8021X, i));
+	g_string_truncate (alt_sub_match, alt_sub_match->len-1);  /* chop off trailing ',' */
+
+	phase2_alt_sub_match = g_string_new (NULL);
+	for (i = 0; i < nm_setting_802_1x_get_num_phase2_altsubject_matches (s_8021X); i++)
+		g_string_append_printf (phase2_alt_sub_match, "%s,", nm_setting_802_1x_get_phase2_altsubject_match (s_8021X, i));
+	g_string_truncate (phase2_alt_sub_match, phase2_alt_sub_match->len-1);  /* chop off trailing ',' */
+
 	nmc->allowed_fields[0].value = NM_SETTING_802_1X_SETTING_NAME;
 	nmc->allowed_fields[1].value = eap_str->str;
 	nmc->allowed_fields[2].value = nm_setting_802_1x_get_identity (s_8021X);
 	nmc->allowed_fields[3].value = nm_setting_802_1x_get_anonymous_identity (s_8021X);
 	nmc->allowed_fields[4].value = ca_cert_str;
 	nmc->allowed_fields[5].value = nm_setting_802_1x_get_ca_path (s_8021X);
-	nmc->allowed_fields[6].value = client_cert_str;
-	nmc->allowed_fields[7].value = nm_setting_802_1x_get_phase1_peapver (s_8021X);
-	nmc->allowed_fields[8].value = nm_setting_802_1x_get_phase1_peaplabel (s_8021X);
-	nmc->allowed_fields[9].value = nm_setting_802_1x_get_phase1_fast_provisioning (s_8021X);
-	nmc->allowed_fields[10].value = nm_setting_802_1x_get_phase2_auth (s_8021X);
-	nmc->allowed_fields[11].value = nm_setting_802_1x_get_phase2_autheap (s_8021X);
-	nmc->allowed_fields[12].value = phase2_ca_cert_str;
-	nmc->allowed_fields[13].value = nm_setting_802_1x_get_phase2_ca_path (s_8021X);
-	nmc->allowed_fields[14].value = phase2_client_cert_str;
-	nmc->allowed_fields[15].value = nm_setting_802_1x_get_password (s_8021X);
-	nmc->allowed_fields[16].value = private_key_str;
-	nmc->allowed_fields[17].value = nm_setting_802_1x_get_private_key_password (s_8021X);
-	nmc->allowed_fields[18].value = phase2_private_key_str;
-	nmc->allowed_fields[19].value = nm_setting_802_1x_get_phase2_private_key_password (s_8021X);
-	nmc->allowed_fields[20].value = nm_setting_802_1x_get_pin (s_8021X);
-	nmc->allowed_fields[21].value = nm_setting_802_1x_get_system_ca_certs (s_8021X) ? _("yes") : _("no");
+	nmc->allowed_fields[6].value = nm_setting_802_1x_get_subject_match (s_8021X);
+	nmc->allowed_fields[7].value = alt_sub_match->str;
+	nmc->allowed_fields[8].value = client_cert_str;
+	nmc->allowed_fields[9].value = nm_setting_802_1x_get_phase1_peapver (s_8021X);
+	nmc->allowed_fields[10].value = nm_setting_802_1x_get_phase1_peaplabel (s_8021X);
+	nmc->allowed_fields[11].value = nm_setting_802_1x_get_phase1_fast_provisioning (s_8021X);
+	nmc->allowed_fields[12].value = nm_setting_802_1x_get_phase2_auth (s_8021X);
+	nmc->allowed_fields[13].value = nm_setting_802_1x_get_phase2_autheap (s_8021X);
+	nmc->allowed_fields[14].value = phase2_ca_cert_str;
+	nmc->allowed_fields[15].value = nm_setting_802_1x_get_phase2_ca_path (s_8021X);
+	nmc->allowed_fields[16].value = nm_setting_802_1x_get_phase2_subject_match (s_8021X);
+	nmc->allowed_fields[17].value = phase2_alt_sub_match->str;
+	nmc->allowed_fields[18].value = phase2_client_cert_str;
+	nmc->allowed_fields[19].value = nm_setting_802_1x_get_password (s_8021X);
+	nmc->allowed_fields[20].value = private_key_str;
+	nmc->allowed_fields[21].value = nm_setting_802_1x_get_private_key_password (s_8021X);
+	nmc->allowed_fields[22].value = phase2_private_key_str;
+	nmc->allowed_fields[23].value = nm_setting_802_1x_get_phase2_private_key_password (s_8021X);
+	nmc->allowed_fields[24].value = nm_setting_802_1x_get_pin (s_8021X);
+	nmc->allowed_fields[25].value = nm_setting_802_1x_get_system_ca_certs (s_8021X) ? _("yes") : _("no");
 
 	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
 	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
@@ -672,6 +762,8 @@ setting_802_1X_details (NMSetting *setting, NmCli *nmc)
 	g_free (private_key_str);
 	g_free (phase2_private_key_str);
 	g_string_free (eap_str, TRUE);
+	g_string_free (alt_sub_match, TRUE);
+	g_string_free (phase2_alt_sub_match, TRUE);
 
 	return TRUE;
 }
@@ -684,7 +776,8 @@ setting_wireless_details (NMSetting *setting, NmCli *nmc)
 	const GByteArray *ssid, *bssid, *mac;
 	char *ssid_str, *channel_str, *rate_str, *tx_power_str, *mtu_str;
 	char *device_mac_str = NULL, *cloned_mac_str = NULL, *bssid_str = NULL;
-	GString *seen_bssids;
+	GString *mac_blacklist, *seen_bssids;
+	const GSList *iter;
 	guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
 	guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
 	guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
@@ -712,6 +805,15 @@ setting_wireless_details (NMSetting *setting, NmCli *nmc)
 	mac = nm_setting_wireless_get_cloned_mac_address (s_wireless);
 	if (mac)
 		cloned_mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);
+
+	mac_blacklist = g_string_new (NULL);
+	iter = nm_setting_wireless_get_mac_address_blacklist (s_wireless);
+	while (iter) {
+		g_string_append_printf (mac_blacklist, "%s,", (char *) iter->data);
+		iter = iter->next;
+	}
+	g_string_truncate (mac_blacklist, mac_blacklist->len-1);  /* chop off trailing ',' */
+
 	seen_bssids = g_string_new (NULL);
 	for (i = 0; i < nm_setting_wireless_get_num_seen_bssids (s_wireless); i++) {
 		if (i > 0)
@@ -729,9 +831,10 @@ setting_wireless_details (NMSetting *setting, NmCli *nmc)
 	nmc->allowed_fields[7].value = tx_power_str;
 	nmc->allowed_fields[8].value = device_mac_str ? device_mac_str : _("not set");
 	nmc->allowed_fields[9].value = cloned_mac_str ? cloned_mac_str : _("not set");
-	nmc->allowed_fields[10].value = strcmp (mtu_str, "0") ?  mtu_str : _("auto");
-	nmc->allowed_fields[11].value = seen_bssids->str;
-	nmc->allowed_fields[12].value = nm_setting_wireless_get_security (s_wireless);
+	nmc->allowed_fields[10].value = mac_blacklist->str;
+	nmc->allowed_fields[11].value = strcmp (mtu_str, "0") ?  mtu_str : _("auto");
+	nmc->allowed_fields[12].value = seen_bssids->str;
+	nmc->allowed_fields[13].value = nm_setting_wireless_get_security (s_wireless);
 
 	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
 	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
@@ -745,6 +848,7 @@ setting_wireless_details (NMSetting *setting, NmCli *nmc)
 	g_free (cloned_mac_str);
 	g_free (mtu_str);
 	g_string_free (seen_bssids, TRUE);
+	g_string_free (mac_blacklist, TRUE);
 
 	return TRUE;
 }
@@ -940,6 +1044,7 @@ setting_ip4_config_details (NMSetting *setting, NmCli *nmc)
 	nmc->allowed_fields[9].value = nm_setting_ip4_config_get_dhcp_send_hostname (s_ip4) ? _("yes") : _("no");
 	nmc->allowed_fields[10].value = nm_setting_ip4_config_get_dhcp_hostname (s_ip4);
 	nmc->allowed_fields[11].value = nm_setting_ip4_config_get_never_default (s_ip4) ? _("yes") : _("no");
+	nmc->allowed_fields[12].value = nm_setting_ip4_config_get_may_fail (s_ip4) ? _("yes") : _("no");
 
 	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
 	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
@@ -1019,6 +1124,11 @@ setting_ip6_config_details (NMSetting *setting, NmCli *nmc)
 		g_string_append (addr_str, tmp);
 		g_free (tmp);
 
+		memset (buf, 0, sizeof (buf));
+		ip = nm_ip6_address_get_gateway (addr);
+		inet_ntop (AF_INET6, (const void *) ip, buf, sizeof (buf));
+		g_string_append_printf (addr_str, ", gw = %s", buf);
+
 		g_string_append (addr_str, " }");
 	}
 
@@ -1067,6 +1177,7 @@ setting_ip6_config_details (NMSetting *setting, NmCli *nmc)
 	nmc->allowed_fields[6].value = nm_setting_ip6_config_get_ignore_auto_routes (s_ip6) ? _("yes") : _("no");
 	nmc->allowed_fields[7].value = nm_setting_ip6_config_get_ignore_auto_dns (s_ip6) ? _("yes") : _("no");
 	nmc->allowed_fields[8].value = nm_setting_ip6_config_get_never_default (s_ip6) ? _("yes") : _("no");
+	nmc->allowed_fields[9].value = nm_setting_ip6_config_get_may_fail (s_ip6) ? _("yes") : _("no");
 
 	nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
 	print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
diff --git a/cli/src/utils.c b/cli/src/utils.c
index 3c4e4f36..c5637e4f 100644
--- a/cli/src/utils.c
+++ b/cli/src/utils.c
@@ -194,6 +194,7 @@ print_fields (const NmcPrintFields fields, const NmcOutputField field_values[])
 	if (multiline) {
 	/* --- Multiline mode --- */
 		enum { ML_HEADER_WIDTH = 79 };
+		enum { ML_VALUE_INDENT = 40 };
 		if (main_header && pretty) {
 			/* Print the main header */
 			int header_width = nmc_string_screen_width (fields.header_name, NULL) + 4;
@@ -218,7 +219,7 @@ print_fields (const NmcPrintFields fields, const NmcOutputField field_values[])
 				tmp = g_strdup_printf ("%s%s%s:", section_prefix ? field_values[0].value : "",
 				                                  section_prefix ? "." : "",
 				                                  _(field_values[idx].name_l10n));
-				printf ("%-*s%s\n", terse ? 0 : 32, tmp, field_values[idx].value ? field_values[idx].value : not_set_str);
+				printf ("%-*s%s\n", terse ? 0 : ML_VALUE_INDENT, tmp, field_values[idx].value ? field_values[idx].value : not_set_str);
 				g_free (tmp);
 			}
 			if (pretty) {