summary refs log tree commit diff
path: root/libnm-util/nm-setting-vlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-util/nm-setting-vlan.c')
-rw-r--r--libnm-util/nm-setting-vlan.c80
1 files changed, 64 insertions, 16 deletions
diff --git a/libnm-util/nm-setting-vlan.c b/libnm-util/nm-setting-vlan.c
index f69e0d85..df7f0702 100644
--- a/libnm-util/nm-setting-vlan.c
+++ b/libnm-util/nm-setting-vlan.c
@@ -21,12 +21,16 @@
  * (C) Copyright 2011 - 2012 Red Hat, Inc.
  */
 
+#include <stdlib.h>
+#include <string.h>
 #include <dbus/dbus-glib.h>
+
 #include "nm-setting-vlan.h"
 #include "nm-param-spec-specialized.h"
 #include "nm-utils.h"
 #include "nm-dbus-glib-types.h"
 #include "nm-setting-connection.h"
+#include "nm-setting-private.h"
 
 /**
  * SECTION:nm-setting-vlan
@@ -54,7 +58,12 @@ nm_setting_vlan_error_quark (void)
 	return quark;
 }
 
-G_DEFINE_TYPE (NMSettingVlan, nm_setting_vlan, NM_TYPE_SETTING)
+G_DEFINE_TYPE_WITH_CODE (NMSettingVlan, nm_setting_vlan, NM_TYPE_SETTING,
+                         _nm_register_setting (NM_SETTING_VLAN_SETTING_NAME,
+                                               g_define_type_id,
+                                               1,
+                                               NM_SETTING_VLAN_ERROR))
+NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_VLAN)
 
 #define NM_SETTING_VLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_VLAN, NMSettingVlanPrivate))
 
@@ -436,29 +445,68 @@ static gboolean
 verify (NMSetting *setting, GSList *all_settings, GError **error)
 {
 	NMSettingVlanPrivate *priv = NM_SETTING_VLAN_GET_PRIVATE (setting);
-
-	if (priv->iface_name && !priv->iface_name[0]) {
-		g_set_error (error,
-		             NM_SETTING_VLAN_ERROR,
-		             NM_SETTING_VLAN_ERROR_INVALID_PROPERTY,
-		             NM_SETTING_VLAN_INTERFACE_NAME);
-		return FALSE;
+	NMSettingConnection *s_con = NULL;
+	NMSettingWired *s_wired = NULL;
+	GSList *iter;
+
+	for (iter = all_settings; iter; iter = iter->next) {
+		if (NM_IS_SETTING_CONNECTION (iter->data))
+			s_con = iter->data;
+		else if (NM_IS_SETTING_WIRED (iter->data))
+			s_wired = iter->data;
 	}
 
-	if (priv->parent && !priv->parent[0]) {
+	/* If iface_name is specified, it must be a valid interface name. We
+	 * don't check that it matches parent and/or id, because we allowing
+	 * renaming vlans to arbitrary names.
+	 */
+	if (priv->iface_name && !nm_utils_iface_valid_name (priv->iface_name)) {
 		g_set_error (error,
 		             NM_SETTING_VLAN_ERROR,
 		             NM_SETTING_VLAN_ERROR_INVALID_PROPERTY,
-		             NM_SETTING_VLAN_PARENT);
+		             NM_SETTING_VLAN_INTERFACE_NAME);
 		return FALSE;
 	}
 
-	if (priv->id > 4095) {
-		g_set_error (error,
-		             NM_SETTING_VLAN_ERROR,
-		             NM_SETTING_VLAN_ERROR_INVALID_PROPERTY,
-		             NM_SETTING_VLAN_ID);
-		return FALSE;
+	if (priv->parent) {
+		if (nm_utils_is_uuid (priv->parent)) {
+			/* If we have an NMSettingConnection:master with slave-type="vlan",
+			 * then it must be the same UUID.
+			 */
+			if (s_con) {
+				const char *master = NULL, *slave_type = NULL;
+
+				slave_type = nm_setting_connection_get_slave_type (s_con);
+				if (!g_strcmp0 (slave_type, NM_SETTING_VLAN_SETTING_NAME))
+					master = nm_setting_connection_get_master (s_con);
+
+				if (master && g_strcmp0 (priv->parent, master) != 0) {
+					g_set_error (error,
+					             NM_SETTING_VLAN_ERROR,
+					             NM_SETTING_VLAN_ERROR_INVALID_PARENT,
+					             NM_SETTING_CONNECTION_MASTER);
+					return FALSE;
+				}
+			}
+		} else if (!nm_utils_iface_valid_name (priv->parent)) {
+			/* parent must be either a UUID or an interface name */
+			g_set_error (error,
+			             NM_SETTING_VLAN_ERROR,
+			             NM_SETTING_VLAN_ERROR_INVALID_PROPERTY,
+			             NM_SETTING_VLAN_PARENT);
+			return FALSE;
+		} 
+	} else {
+		/* If parent is NULL, the parent must be specified via
+		 * NMSettingWired:mac-address.
+		 */
+		if (!s_wired || !nm_setting_wired_get_mac_address (s_wired)) {
+			g_set_error (error,
+			             NM_SETTING_VLAN_ERROR,
+			             NM_SETTING_VLAN_ERROR_MISSING_PROPERTY,
+			             NM_SETTING_VLAN_PARENT);
+			return FALSE;
+		}
 	}
 
 	if (priv->flags & ~(NM_VLAN_FLAG_REORDER_HEADERS |