summary refs log tree commit diff
path: root/libnm-util/nm-setting-infiniband.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-util/nm-setting-infiniband.c')
-rw-r--r--libnm-util/nm-setting-infiniband.c183
1 files changed, 160 insertions, 23 deletions
diff --git a/libnm-util/nm-setting-infiniband.c b/libnm-util/nm-setting-infiniband.c
index ee40aa0e..5af50448 100644
--- a/libnm-util/nm-setting-infiniband.c
+++ b/libnm-util/nm-setting-infiniband.c
@@ -16,16 +16,20 @@
  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301 USA.
  *
- * Copyright 2011 Red Hat, Inc.
+ * Copyright 2011 - 2013 Red Hat, Inc.
  */
 
+#include <stdlib.h>
 #include <dbus/dbus-glib.h>
 #include <linux/if_infiniband.h>
+#include <glib/gi18n.h>
 
 #include "nm-setting-infiniband.h"
 #include "nm-param-spec-specialized.h"
+#include "nm-utils.h"
 #include "nm-utils-private.h"
 #include "nm-setting-private.h"
+#include "nm-setting-connection.h"
 
 /**
  * SECTION:nm-setting-infiniband
@@ -66,6 +70,8 @@ typedef struct {
 	GByteArray *mac_address;
 	char *transport_mode;
 	guint32 mtu;
+	int p_key;
+	char *parent, *virtual_iface_name;
 } NMSettingInfinibandPrivate;
 
 enum {
@@ -73,6 +79,8 @@ enum {
 	PROP_MAC_ADDRESS,
 	PROP_MTU,
 	PROP_TRANSPORT_MODE,
+	PROP_P_KEY,
+	PROP_PARENT,
 
 	LAST_PROP
 };
@@ -135,6 +143,53 @@ nm_setting_infiniband_get_transport_mode (NMSettingInfiniband *setting)
 	return NM_SETTING_INFINIBAND_GET_PRIVATE (setting)->transport_mode;
 }
 
+/**
+ * nm_setting_infiniband_get_p_key:
+ * @setting: the #NMSettingInfiniband
+ *
+ * Returns the P_Key to use for this device. A value of -1 means to
+ * use the default P_Key (aka "the P_Key at index 0"). Otherwise it is
+ * a 16-bit unsigned integer.
+ *
+ * Returns: the IPoIB P_Key
+ **/
+int
+nm_setting_infiniband_get_p_key (NMSettingInfiniband *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_INFINIBAND (setting), -1);
+
+	return NM_SETTING_INFINIBAND_GET_PRIVATE (setting)->p_key;
+}
+
+/**
+ * nm_setting_infiniband_get_parent:
+ * @setting: the #NMSettingInfiniband
+ *
+ * Returns the parent interface name for this device, if set.
+ *
+ * Returns: the parent interface name
+ **/
+const char *
+nm_setting_infiniband_get_parent (NMSettingInfiniband *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_INFINIBAND (setting), NULL);
+
+	return NM_SETTING_INFINIBAND_GET_PRIVATE (setting)->parent;
+}
+
+static const char *
+get_virtual_iface_name (NMSetting *setting)
+{
+	NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE (setting);
+
+	if (priv->p_key == -1 || !priv->parent)
+		return NULL;
+
+	if (!priv->virtual_iface_name)
+		priv->virtual_iface_name = g_strdup_printf ("%s.%04x", priv->parent, priv->p_key);
+
+	return NM_SETTING_INFINIBAND_GET_PRIVATE (setting)->virtual_iface_name;
+}
 
 static gboolean
 verify (NMSetting *setting, GSList *all_settings, GError **error)
@@ -142,10 +197,11 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
 	NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE (setting);
 
 	if (priv->mac_address && priv->mac_address->len != INFINIBAND_ALEN) {
-		g_set_error (error,
-		             NM_SETTING_INFINIBAND_ERROR,
-		             NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY,
-		             NM_SETTING_INFINIBAND_MAC_ADDRESS);
+		g_set_error_literal (error,
+		                     NM_SETTING_INFINIBAND_ERROR,
+		                     NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY,
+		                     _("property is invalid"));
+		g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MAC_ADDRESS);
 		return FALSE;
 	}
 
@@ -156,20 +212,49 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
 		if (priv->mtu > 65520)
 			priv->mtu = 65520;
 	} else {
-		g_set_error (error,
-		             NM_SETTING_INFINIBAND_ERROR,
-		             NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY,
-		             NM_SETTING_INFINIBAND_TRANSPORT_MODE);
+		g_set_error_literal (error,
+		                     NM_SETTING_INFINIBAND_ERROR,
+		                     NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY,
+		                     _("property is invalid"));
+		g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_TRANSPORT_MODE);
 		return FALSE;
 	}
 
+	if (priv->parent) {
+		if (!nm_utils_iface_valid_name (priv->parent)) {
+			g_set_error_literal (error,
+			                     NM_SETTING_INFINIBAND_ERROR,
+			                     NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY,
+			                     _("not a valid interface name"));
+			g_prefix_error (error, "%s: ", NM_SETTING_INFINIBAND_PARENT);
+			return FALSE;
+		}
+		if (priv->p_key == -1) {
+			g_set_error_literal (error,
+			                     NM_SETTING_INFINIBAND_ERROR,
+			                     NM_SETTING_INFINIBAND_ERROR_INVALID_PROPERTY,
+			                     _("Must specify a P_Key if specifying parent"));
+			g_prefix_error (error, "%s: ", NM_SETTING_INFINIBAND_PARENT);
+		}
+	}
+
+	if (priv->p_key != -1) {
+		if (!priv->mac_address && !priv->parent) {
+			g_set_error_literal (error,
+			                     NM_SETTING_INFINIBAND_ERROR,
+			                     NM_SETTING_INFINIBAND_ERROR_MISSING_PROPERTY,
+			                     _("InfiniBand P_Key connection did not specify parent interface name"));
+			g_prefix_error (error, "%s: ", NM_SETTING_INFINIBAND_PARENT);
+			return FALSE;
+		}
+	}
+
 	return TRUE;
 }
 
 static void
 nm_setting_infiniband_init (NMSettingInfiniband *setting)
 {
-	g_object_set (setting, NM_SETTING_NAME, NM_SETTING_INFINIBAND_SETTING_NAME, NULL);
 }
 
 static void
@@ -180,6 +265,8 @@ finalize (GObject *object)
 	g_free (priv->transport_mode);
 	if (priv->mac_address)
 		g_byte_array_free (priv->mac_address, TRUE);
+	g_free (priv->parent);
+	g_free (priv->virtual_iface_name);
 
 	G_OBJECT_CLASS (nm_setting_infiniband_parent_class)->finalize (object);
 }
@@ -203,6 +290,15 @@ set_property (GObject *object, guint prop_id,
 		g_free (priv->transport_mode);
 		priv->transport_mode = g_value_dup_string (value);
 		break;
+	case PROP_P_KEY:
+		priv->p_key = g_value_get_int (value);
+		g_clear_pointer (&priv->virtual_iface_name, g_free);
+		break;
+	case PROP_PARENT:
+		g_free (priv->parent);
+		priv->parent = g_value_dup_string (value);
+		g_clear_pointer (&priv->virtual_iface_name, g_free);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -225,6 +321,12 @@ get_property (GObject *object, guint prop_id,
 	case PROP_TRANSPORT_MODE:
 		g_value_set_string (value, nm_setting_infiniband_get_transport_mode (setting));
 		break;
+	case PROP_P_KEY:
+		g_value_set_int (value, nm_setting_infiniband_get_p_key (setting));
+		break;
+	case PROP_PARENT:
+		g_value_set_string (value, nm_setting_infiniband_get_parent (setting));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -243,15 +345,17 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *setting_class)
 	object_class->set_property = set_property;
 	object_class->get_property = get_property;
 	object_class->finalize     = finalize;
-	parent_class->verify       = verify;
+
+	parent_class->verify                 = verify;
+	parent_class->get_virtual_iface_name = get_virtual_iface_name;
 
 	/* Properties */
 	/**
 	 * NMSettingInfiniband:mac-address:
 	 *
-	 * If specified, this connection will only apply to the IPoIB
-	 * device whose permanent MAC address matches. This property does
-	 * not change the MAC address of the device (i.e. MAC spoofing).
+	 * If specified, this connection will only apply to the IPoIB device whose
+	 * permanent MAC address matches. This property does not change the MAC
+	 * address of the device (i.e. MAC spoofing).
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_MAC_ADDRESS,
@@ -262,7 +366,7 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *setting_class)
 		                             "This property does not change the MAC address "
 		                             "of the device (i.e. MAC spoofing).",
 		                             DBUS_TYPE_G_UCHAR_ARRAY,
-		                             G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+		                             G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE));
 
 	/**
 	 * NMSettingInfiniband:mtu:
@@ -278,20 +382,53 @@ nm_setting_infiniband_class_init (NMSettingInfinibandClass *setting_class)
 		                    "size or smaller, breaking larger packets up into "
 		                    "multiple frames.",
 		                    0, G_MAXUINT32, 0,
-		                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE));
+		                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_FUZZY_IGNORE));
 
 	/**
 	 * NMSettingInfiniband:transport-mode:
 	 *
-	 * The IP-over-InfiniBand transport mode. Either 'datagram' or
-	 * 'connected'.
+	 * The IP-over-InfiniBand transport mode. Either "datagram" or
+	 * "connected".
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_TRANSPORT_MODE,
 		 g_param_spec_string (NM_SETTING_INFINIBAND_TRANSPORT_MODE,
-							  "Transport Mode",
-							  "The IPoIB transport mode. Either 'datagram' or 'connected'.",
-							  NULL,
-							  G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
-}
+		                      "Transport Mode",
+		                      "The IPoIB transport mode. Either 'datagram' or 'connected'.",
+		                      NULL,
+		                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE));
 
+	/**
+	 * NMSettingInfiniband:p-key:
+	 *
+	 * The InfiniBand P_Key to use for this device. A value of -1 means to use
+	 * the default P_Key (aka "the P_Key at index 0").  Otherwise it is a 16-bit
+	 * unsigned integer, whose high bit is set if it is a "full membership"
+	 * P_Key.
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_P_KEY,
+		 g_param_spec_int (NM_SETTING_INFINIBAND_P_KEY,
+		                   "P_Key",
+		                   "The InfiniBand P_Key. Either -1 for the "
+		                   "default, or a 16-bit unsigned integer.",
+		                   -1, 0xFFFF, -1,
+		                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE));
+
+	/**
+	 * NMSettingInfiniband:parent:
+	 *
+	 * The interface name of the parent device of this device. Normally %NULL,
+	 * but if the #NMSettingInfiniband:p_key property is set, then you must
+	 * specify the base device by setting either this property or
+	 * #NMSettingInfiniband:mac-address.
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_PARENT,
+		 g_param_spec_string (NM_SETTING_INFINIBAND_PARENT,
+		                      "Parent",
+		                      "The interface name of the parent device, or NULL",
+		                      NULL,
+		                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE));
+
+}