diff --git a/lib/bootstrap.py b/lib/bootstrap.py
index 11e1f6ee6d91e9f1f00cdcc659dd89b7aaea9a5f..277b5cbe9d45ed13f6c3bc1a14a229adff9a2101 100644
--- a/lib/bootstrap.py
+++ b/lib/bootstrap.py
@@ -223,7 +223,8 @@ def InitCluster(cluster_name, mac_prefix,
                 nicparams=None, hvparams=None, enabled_hypervisors=None,
                 modify_etc_hosts=True, modify_ssh_setup=True,
                 maintain_node_health=False, drbd_helper=None,
-                uid_pool=None, default_iallocator=None):
+                uid_pool=None, default_iallocator=None,
+                primary_ip_version=None):
   """Initialise the cluster.
 
   @type candidate_pool_size: int
@@ -244,39 +245,56 @@ def InitCluster(cluster_name, mac_prefix,
                                " entries: %s" % invalid_hvs,
                                errors.ECODE_INVAL)
 
-  hostname = netutils.GetHostname()
 
-  if netutils.IP4Address.IsLoopback(hostname.ip):
+  ipcls = None
+  if primary_ip_version == constants.IP4_VERSION:
+    ipcls = netutils.IP4Address
+  elif primary_ip_version == constants.IP6_VERSION:
+    ipcls = netutils.IP6Address
+  else:
+    raise errors.OpPrereqError("Invalid primary ip version: %d." %
+                               primary_ip_version)
+
+  hostname = netutils.GetHostname(family=ipcls.family)
+  if not ipcls.IsValid(hostname.ip):
+    raise errors.OpPrereqError("This host's IP (%s) is not a valid IPv%d"
+                               " address." % (hostname.ip, primary_ip_version))
+
+  if ipcls.IsLoopback(hostname.ip):
     raise errors.OpPrereqError("This host's IP (%s) resolves to a loopback"
                                " address. Please fix DNS or %s." %
                                (hostname.ip, constants.ETC_HOSTS),
                                errors.ECODE_ENVIRON)
 
-  if not netutils.IPAddress.Own(hostname.ip):
+  if not ipcls.Own(hostname.ip):
     raise errors.OpPrereqError("Inconsistency: this host's name resolves"
                                " to %s,\nbut this ip address does not"
                                " belong to this host. Aborting." %
                                hostname.ip, errors.ECODE_ENVIRON)
 
-  clustername = netutils.GetHostname(name=cluster_name)
+  clustername = netutils.GetHostname(name=cluster_name, family=ipcls.family)
 
-  if netutils.TcpPing(clustername.ip, constants.DEFAULT_NODED_PORT,
-                   timeout=5):
+  if netutils.TcpPing(clustername.ip, constants.DEFAULT_NODED_PORT, timeout=5):
     raise errors.OpPrereqError("Cluster IP already active. Aborting.",
                                errors.ECODE_NOTUNIQUE)
 
-  if secondary_ip:
-    if not netutils.IP4Address.IsValid(secondary_ip):
-      raise errors.OpPrereqError("Invalid secondary ip given",
-                                 errors.ECODE_INVAL)
-    if (secondary_ip != hostname.ip and
-        not netutils.IPAddress.Own(secondary_ip)):
-      raise errors.OpPrereqError("You gave %s as secondary IP,"
-                                 " but it does not belong to this host." %
-                                 secondary_ip, errors.ECODE_ENVIRON)
-  else:
+  if not secondary_ip:
+    if primary_ip_version == constants.IP6_VERSION:
+      raise errors.OpPrereqError("When using a IPv6 primary address, a valid"
+                                 " IPv4 address must be given as secondary."
+                                 " Aborting.", errors.ECODE_INVAL)
     secondary_ip = hostname.ip
 
+  if not netutils.IP4Address.IsValid(secondary_ip):
+    raise errors.OpPrereqError("Secondary IP address (%s) has to be a valid"
+                               " IPv4 address." % secondary_ip,
+                               errors.ECODE_INVAL)
+
+  if not netutils.IP4Address.Own(secondary_ip):
+    raise errors.OpPrereqError("You gave %s as secondary IP,"
+                               " but it does not belong to this host." %
+                               secondary_ip, errors.ECODE_ENVIRON)
+
   if vg_name is not None:
     # Check if volume group is valid
     vgstatus = utils.CheckVolumeGroupSize(utils.ListVolumeGroups(), vg_name,
@@ -373,6 +391,7 @@ def InitCluster(cluster_name, mac_prefix,
     maintain_node_health=maintain_node_health,
     drbd_usermode_helper=drbd_helper,
     default_iallocator=default_iallocator,
+    primary_ip_family=ipcls.family,
     )
   master_node_config = objects.Node(name=hostname.name,
                                     primary_ip=hostname.ip,
diff --git a/lib/constants.py b/lib/constants.py
index ce4c6f1b18b95b5bd109ec00a4ba0efd13e64642..74495a97a5cb973922f74668f59bf6eece1681f8 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -450,6 +450,8 @@ IP4_ADDRESS_LOCALHOST = "127.0.0.1"
 IP4_ADDRESS_ANY = "0.0.0.0"
 IP6_ADDRESS_LOCALHOST = "::1"
 IP6_ADDRESS_ANY = "::"
+IP4_VERSION = 4
+IP6_VERSION = 6
 TCP_PING_TIMEOUT = 10
 GANETI_RUNAS = "root"
 DEFAULT_VG = "xenvg"
diff --git a/lib/objects.py b/lib/objects.py
index 8b5e1e7a9deb6571ffd9d35aff95caa6b0d35d18..d59f41754b01b50a981e998a83ef848c76c4ebb2 100644
--- a/lib/objects.py
+++ b/lib/objects.py
@@ -1,7 +1,7 @@
 #
 #
 
-# Copyright (C) 2006, 2007 Google Inc.
+# Copyright (C) 2006, 2007, 2010 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -919,6 +919,7 @@ class Cluster(TaggableObject):
     "maintain_node_health",
     "uid_pool",
     "default_iallocator",
+    "primary_ip_family",
     ] + _TIMESTAMPS + _UUID
 
   def UpgradeConfig(self):
diff --git a/scripts/gnt-cluster b/scripts/gnt-cluster
index efd49eaa44a3cf1e8e71dbcc403fbef86246a3cf..2da37fdcdc1daa96a201641612d6c990195c5a5e 100755
--- a/scripts/gnt-cluster
+++ b/scripts/gnt-cluster
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 #
 
-# Copyright (C) 2006, 2007 Google Inc.
+# Copyright (C) 2006, 2007, 2010 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -122,6 +122,7 @@ def InitCluster(opts, args):
                         drbd_helper=drbd_helper,
                         uid_pool=uid_pool,
                         default_iallocator=opts.default_iallocator,
+                        primary_ip_version=constants.IP4_VERSION,
                         )
   op = opcodes.OpPostInitCluster()
   SubmitOpCode(op, opts=opts)