diff --git a/pkgs/tools/networking/unbound/default.nix b/pkgs/tools/networking/unbound/default.nix
index e1a7a685b140..e15947332681 100644
--- a/pkgs/tools/networking/unbound/default.nix
+++ b/pkgs/tools/networking/unbound/default.nix
@@ -11,6 +11,15 @@ stdenv.mkDerivation rec {
 
   buildInputs = [openssl expat libevent];
 
+  patches = [
+    # This patch fixes unbound 1.5.1 on linux versions previous to 3.15 which
+    # do not implement IP_PMTUDISC_OMIT.
+    #
+    # It should be discarded when this support makes it into a released
+    # version.
+    ./linux-pre-3.15-unbound-1.5.1.patch
+  ];
+
   configureFlags = [
     "--with-ssl=${openssl}"
     "--with-libexpat=${expat}"
diff --git a/pkgs/tools/networking/unbound/linux-pre-3.15-unbound-1.5.1.patch b/pkgs/tools/networking/unbound/linux-pre-3.15-unbound-1.5.1.patch
new file mode 100644
index 000000000000..619568078999
--- /dev/null
+++ b/pkgs/tools/networking/unbound/linux-pre-3.15-unbound-1.5.1.patch
@@ -0,0 +1,66 @@
+--- ./services/listen_dnsport.c	2014-12-10 10:59:31.726514857 +0100
++++ ./services/listen_dnsport.c	2014-12-10 11:08:45.009071300 +0100
+@@ -368,29 +368,47 @@
+  * (and also uses the interface mtu to determine the size of the packets).
+  * So there won't be any EMSGSIZE error.  Against DNS fragmentation attacks.
+  * FreeBSD already has same semantics without setting the option. */
+-#    if defined(IP_PMTUDISC_OMIT)
+-		int action = IP_PMTUDISC_OMIT;
+-#    else
+-		int action = IP_PMTUDISC_DONT;
+-#    endif
++		int omit_set = 0;
++		int action;
++#   if defined(IP_PMTUDISC_OMIT)
++		action = IP_PMTUDISC_OMIT;
+ 		if (setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, 
+ 			&action, (socklen_t)sizeof(action)) < 0) {
+-			log_err("setsockopt(..., IP_MTU_DISCOVER, "
+-#    if defined(IP_PMTUDISC_OMIT)
+-				"IP_PMTUDISC_OMIT"
++
++			if (errno != EINVAL) {
++				log_err("setsockopt(..., IP_MTU_DISCOVER, IP_PMTUDISC_OMIT...) failed: %s",
++					strerror(errno));
++
++#    ifndef USE_WINSOCK
++				close(s);
+ #    else
+-				"IP_PMTUDISC_DONT"
++				closesocket(s);
+ #    endif
+-				"...) failed: %s",
+-				strerror(errno));
++				*noproto = 0;
++				*inuse = 0;
++				return -1;
++			}
++		}
++		else
++		{
++		    omit_set = 1;
++		}
++#   endif
++		if (omit_set == 0) {
++   			action = IP_PMTUDISC_DONT;
++			if (setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER,
++				&action, (socklen_t)sizeof(action)) < 0) {
++				log_err("setsockopt(..., IP_MTU_DISCOVER, IP_PMTUDISC_DONT...) failed: %s",
++					strerror(errno));
+ #    ifndef USE_WINSOCK
+-			close(s);
++				close(s);
+ #    else
+-			closesocket(s);
++				closesocket(s);
+ #    endif
+-			*noproto = 0;
+-			*inuse = 0;
+-			return -1;
++				*noproto = 0;
++				*inuse = 0;
++				return -1;
++			}
+ 		}
+ #  elif defined(IP_DONTFRAG)
+ 		int off = 0;