diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index b9c8014fb933eb86ca229545984dcd086e45af19..8d2721c452f4b6cb1188c410cc1df1bf59f51a40 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -2837,7 +2837,7 @@ class LUCreateInstance(LogicalUnit):
   HTYPE = constants.HTYPE_INSTANCE
   _OP_REQP = ["instance_name", "mem_size", "disk_size", "pnode",
               "disk_template", "swap_size", "mode", "start", "vcpus",
-              "wait_for_sync", "ip_check"]
+              "wait_for_sync", "ip_check", "mac"]
 
   def BuildHooksEnv(self):
     """Build hooks env.
@@ -3013,6 +3013,12 @@ class LUCreateInstance(LogicalUnit):
         raise errors.OpPrereqError("IP %s of instance %s already in use" %
                                    (hostname1.ip, instance_name))
 
+    # MAC address verification
+    if self.op.mac != "auto":
+      if not utils.IsValidMac(self.op.mac.lower()):
+        raise errors.OpPrereqError("invalid MAC address specified: %s" %
+                                   self.op.mac)
+
     # bridge verification
     bridge = getattr(self.op, "bridge", None)
     if bridge is None:
@@ -3037,7 +3043,12 @@ class LUCreateInstance(LogicalUnit):
     instance = self.op.instance_name
     pnode_name = self.pnode.name
 
-    nic = objects.NIC(bridge=self.op.bridge, mac=self.cfg.GenerateMAC())
+    if self.op.mac == "auto":
+      mac_address=self.cfg.GenerateMAC()
+    else:
+      mac_address=self.op.mac
+
+    nic = objects.NIC(bridge=self.op.bridge, mac=mac_address)
     if self.inst_ip is not None:
       nic.ip = self.inst_ip
 
@@ -4073,8 +4084,9 @@ class LUSetInstanceParms(LogicalUnit):
     self.mem = getattr(self.op, "mem", None)
     self.vcpus = getattr(self.op, "vcpus", None)
     self.ip = getattr(self.op, "ip", None)
+    self.mac = getattr(self.op, "mac", None)
     self.bridge = getattr(self.op, "bridge", None)
-    if [self.mem, self.vcpus, self.ip, self.bridge].count(None) == 4:
+    if [self.mem, self.vcpus, self.ip, self.bridge, self.mac].count(None) == 5:
       raise errors.OpPrereqError("No changes submitted")
     if self.mem is not None:
       try:
@@ -4096,6 +4108,12 @@ class LUSetInstanceParms(LogicalUnit):
     else:
       self.do_ip = False
     self.do_bridge = (self.bridge is not None)
+    if self.mac is not None:
+      if self.cfg.IsMacInUse(self.mac):
+        raise errors.OpPrereqError('MAC address %s already in use in cluster' %
+                                   self.mac)
+      if not utils.IsValidMac(self.mac):
+        raise errors.OpPrereqError('Invalid MAC address %s' % self.mac)
 
     instance = self.cfg.GetInstanceInfo(
       self.cfg.ExpandInstanceName(self.op.instance_name))
@@ -4125,6 +4143,9 @@ class LUSetInstanceParms(LogicalUnit):
     if self.bridge:
       instance.nics[0].bridge = self.bridge
       result.append(("bridge", self.bridge))
+    if self.mac:
+      instance.nics[0].mac = self.mac
+      result.append(("mac", self.mac))
 
     self.cfg.AddInstance(instance)
 
diff --git a/lib/config.py b/lib/config.py
index fcf8b9fa06cc2a8d8b162dd2a7cf78d96f6402ea..d8c2605f77ac580b1ddd87cf0e93e87f1e49f84a 100644
--- a/lib/config.py
+++ b/lib/config.py
@@ -96,6 +96,18 @@ class ConfigWriter:
       raise errors.ConfigurationError("Can't generate unique MAC")
     return mac
 
+  def IsMacInUse(self, mac):
+    """Predicate: check if the specified MAC is in use in the Ganeti cluster.
+
+    This only checks instances managed by this cluster, it does not
+    check for potential collisions elsewhere.
+
+    """
+    self._OpenConfig()
+    self._ReleaseLock()
+    all_macs = self._AllMACs()
+    return mac in all_macs
+
   def _ComputeAllLVs(self):
     """Compute the list of all LVs.
 
diff --git a/lib/opcodes.py b/lib/opcodes.py
index 3b248fc3069ad012c6a2c07bc0f8704ce0152bf0..8cbca532da6d8305072729112106737b4be2c3f3 100644
--- a/lib/opcodes.py
+++ b/lib/opcodes.py
@@ -160,7 +160,7 @@ class OpCreateInstance(OpCode):
   __slots__ = ["instance_name", "mem_size", "disk_size", "os_type", "pnode",
                "disk_template", "snode", "swap_size", "mode",
                "vcpus", "ip", "bridge", "src_node", "src_path", "start",
-               "wait_for_sync", "ip_check"]
+               "wait_for_sync", "ip_check", "mac"]
 
 
 class OpReinstallInstance(OpCode):
@@ -257,7 +257,7 @@ class OpQueryInstanceData(OpCode):
 class OpSetInstanceParms(OpCode):
   """Change the parameters of an instance."""
   OP_ID = "OP_INSTANCE_SET_PARMS"
-  __slots__ = ["instance_name", "mem", "vcpus", "ip", "bridge"]
+  __slots__ = ["instance_name", "mem", "vcpus", "ip", "bridge", "mac"]
 
 
 # OS opcodes
diff --git a/lib/utils.py b/lib/utils.py
index d5fe36ea97d4dc1b04c66b41d1e6a1997f578c92..f854f5aaa9031f92cc807cd86bcad85bc9c5147f 100644
--- a/lib/utils.py
+++ b/lib/utils.py
@@ -1055,3 +1055,13 @@ def UniqueSequence(seq):
   """
   seen = set()
   return [i for i in seq if i not in seen and not seen.add(i)]
+
+
+def IsValidMac(mac):
+  """Predicate to check if a MAC address is valid.
+
+  Checks wether the supplied MAC address is formally correct, only
+  accepts colon separated format.
+  """
+  mac_check = re.compile("^([0-9a-f]{2}(:|$)){6}$")
+  return mac_check.match(mac) is not None
diff --git a/scripts/gnt-instance b/scripts/gnt-instance
index fd6f48d6a4af229ad4e8c22796c2a574f3ce123b..07285f09ced0c38b62eb352a55e3ebcf5b44fe88 100755
--- a/scripts/gnt-instance
+++ b/scripts/gnt-instance
@@ -226,7 +226,7 @@ def AddInstance(opts, args):
                                 snode=snode, vcpus=opts.vcpus,
                                 ip=opts.ip, bridge=opts.bridge,
                                 start=opts.start, ip_check=opts.ip_check,
-                                wait_for_sync=opts.wait_for_sync)
+                                wait_for_sync=opts.wait_for_sync, mac=opts.mac)
   SubmitOpCode(op)
   return 0
 
@@ -624,15 +624,16 @@ def SetInstanceParms(opts, args):
   Opts used:
     memory - the new memory size
     vcpus - the new number of cpus
+    mac - the new MAC address of the instance
 
   """
-  if not opts.mem and not opts.vcpus and not opts.ip and not opts.bridge:
+  if not (opts.mem or opts.vcpus or opts.ip or opts.bridge or opts.mac):
     logger.ToStdout("Please give at least one of the parameters.")
     return 1
 
   op = opcodes.OpSetInstanceParms(instance_name=args[0], mem=opts.mem,
                                   vcpus=opts.vcpus, ip=opts.ip,
-                                  bridge=opts.bridge)
+                                  bridge=opts.bridge, mac=opts.mac)
   result = SubmitOpCode(op)
 
   if result:
@@ -701,6 +702,9 @@ add_opts = [
   make_option("-i", "--ip", dest="ip",
               help="IP address ('none' [default], 'auto', or specify address)",
               default='none', type="string", metavar="<ADDRESS>"),
+  make_option("--mac", dest="mac",
+              help="MAC address ('auto' [default], or specify address)",
+              default='auto', type="string", metavar="<MACADDRESS>"),
   make_option("--no-wait-for-sync", dest="wait_for_sync", default=True,
               action="store_false", help="Don't wait for sync (DANGEROUS!)"),
   make_option("-b", "--bridge", dest="bridge",
@@ -808,6 +812,9 @@ commands = {
               make_option("-b", "--bridge", dest="bridge",
                           help="Bridge to connect this instance to",
                           default=None, type="string", metavar="<bridge>"),
+              make_option("--mac", dest="mac",
+                          help="MAC address", default=None,
+                          type="string", metavar="<MACADDRESS>"),
               ],
              "<instance>", "Alters the parameters of an instance"),
   'shutdown': (ShutdownInstance, ARGS_ANY,