summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--lib/systems/platforms.nix6
-rw-r--r--nixos/doc/manual/configuration/ipv4-config.xml2
-rw-r--r--nixos/doc/manual/configuration/ipv6-config.xml2
-rw-r--r--nixos/doc/manual/default.nix2
-rw-r--r--nixos/doc/manual/release-notes/rl-1803.xml40
-rw-r--r--nixos/lib/build-vms.nix4
-rw-r--r--nixos/lib/make-disk-image.nix4
-rw-r--r--nixos/modules/installer/cd-dvd/channel.nix4
-rw-r--r--nixos/modules/installer/cd-dvd/installation-cd-base.nix2
-rw-r--r--nixos/modules/installer/cd-dvd/iso-image.nix62
-rw-r--r--nixos/modules/installer/cd-dvd/system-tarball.nix6
-rw-r--r--nixos/modules/installer/tools/nixos-generate-config.pl2
-rw-r--r--nixos/modules/installer/tools/nixos-version.sh4
-rw-r--r--nixos/modules/installer/tools/tools.nix4
-rw-r--r--nixos/modules/misc/label.nix72
-rw-r--r--nixos/modules/misc/version.nix71
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/rename.nix8
-rw-r--r--nixos/modules/services/misc/nixos-manual.nix6
-rw-r--r--nixos/modules/services/misc/ssm-agent.nix2
-rw-r--r--nixos/modules/services/networking/dhcpcd.nix2
-rw-r--r--nixos/modules/services/security/hologram-agent.nix7
-rw-r--r--nixos/modules/services/ttys/agetty.nix4
-rw-r--r--nixos/modules/system/activation/top-level.nix17
-rw-r--r--nixos/modules/system/boot/plymouth.nix2
-rw-r--r--nixos/modules/tasks/network-interfaces-scripted.nix77
-rw-r--r--nixos/modules/tasks/network-interfaces-systemd.nix10
-rw-r--r--nixos/modules/tasks/network-interfaces.nix138
-rw-r--r--nixos/modules/virtualisation/brightbox-image.nix2
-rw-r--r--nixos/modules/virtualisation/google-compute-image.nix2
-rw-r--r--nixos/modules/virtualisation/virtualbox-host.nix2
-rw-r--r--nixos/modules/virtualisation/virtualbox-image.nix6
-rw-r--r--nixos/release.nix4
-rw-r--r--nixos/tests/bittorrent.nix6
-rw-r--r--nixos/tests/cjdns.nix9
-rw-r--r--nixos/tests/containers-bridge.nix4
-rw-r--r--nixos/tests/containers-extra_veth.nix6
-rw-r--r--nixos/tests/containers-hosts.nix6
-rw-r--r--nixos/tests/containers-macvlans.nix8
-rw-r--r--nixos/tests/containers-physical_interfaces.nix24
-rw-r--r--nixos/tests/containers-reloadable.nix2
-rw-r--r--nixos/tests/containers-restart_networking.nix14
-rw-r--r--nixos/tests/ferm.nix8
-rw-r--r--nixos/tests/initrd-network-ssh/default.nix4
-rw-r--r--nixos/tests/ipv6.nix2
-rw-r--r--nixos/tests/nat.nix2
-rw-r--r--nixos/tests/networking.nix129
-rw-r--r--nixos/tests/nsd.nix22
-rw-r--r--nixos/tests/quagga.nix2
-rw-r--r--pkgs/applications/editors/leo-editor/default.nix21
-rw-r--r--pkgs/applications/misc/jekyll/Gemfile.lock70
-rw-r--r--pkgs/applications/misc/jekyll/default.nix13
-rw-r--r--pkgs/applications/misc/jekyll/gemset.nix145
-rw-r--r--pkgs/build-support/fetchurl/default.nix33
-rw-r--r--pkgs/development/interpreters/clojure/default.nix4
-rw-r--r--pkgs/development/libraries/aspell/dictionaries.nix152
-rw-r--r--pkgs/development/ocaml-modules/bitv/default.nix27
-rw-r--r--pkgs/development/tools/analysis/radare2/default.nix25
-rw-r--r--pkgs/development/tools/build-managers/gnumake/4.2/default.nix4
-rw-r--r--pkgs/development/tools/build-managers/gnumake/4.2/head.nix69
-rw-r--r--pkgs/development/tools/build-managers/gnumake/4.2/impure-dirs-head.patch31
-rw-r--r--pkgs/development/tools/misc/binutils/2.30.nix131
-rw-r--r--pkgs/misc/riscv-pk/default.nix5
-rw-r--r--pkgs/os-specific/linux/kernel/linux-riscv.nix18
-rw-r--r--pkgs/os-specific/linux/kernel/patches.nix16
-rw-r--r--pkgs/os-specific/linux/kernel/riscv-install.patch65
-rw-r--r--pkgs/os-specific/linux/kernel/riscv-irq-busy.patch42
-rw-r--r--pkgs/os-specific/linux/kernel/riscv-modules.patch11
-rw-r--r--pkgs/os-specific/linux/powertop/default.nix2
-rw-r--r--pkgs/stdenv/darwin/default.nix1
-rw-r--r--pkgs/stdenv/freebsd/default.nix3
-rw-r--r--pkgs/stdenv/generic/check-meta.nix2
-rw-r--r--pkgs/stdenv/generic/make-derivation.nix4
-rw-r--r--pkgs/stdenv/native/default.nix2
-rw-r--r--pkgs/tools/package-management/nix/default.nix6
-rw-r--r--pkgs/tools/security/afl/default.nix7
-rw-r--r--pkgs/top-level/all-packages.nix29
-rw-r--r--pkgs/top-level/ocaml-packages.nix2
78 files changed, 1343 insertions, 422 deletions
diff --git a/lib/systems/platforms.nix b/lib/systems/platforms.nix
index 3106c05dd5d2..938368db02f0 100644
--- a/lib/systems/platforms.nix
+++ b/lib/systems/platforms.nix
@@ -545,6 +545,12 @@ rec {
     name = "riscv-multiplatform";
     kernelArch = "riscv";
     bfdEmulation = "elf${bits}lriscv";
+    kernelTarget = "vmlinux";
+    kernelAutoModules = true;
+    kernelBaseConfig = "defconfig";
+    kernelExtraConfig = ''
+      FTRACE n
+    '';
   };
 
   selectBySystem = system: {
diff --git a/nixos/doc/manual/configuration/ipv4-config.xml b/nixos/doc/manual/configuration/ipv4-config.xml
index 053501b1736d..68238b547d60 100644
--- a/nixos/doc/manual/configuration/ipv4-config.xml
+++ b/nixos/doc/manual/configuration/ipv4-config.xml
@@ -12,7 +12,7 @@ interfaces.  However, you can configure an interface manually as
 follows:
 
 <programlisting>
-networking.interfaces.eth0.ip4 = [ { address = "192.168.1.2"; prefixLength = 24; } ];
+networking.interfaces.eth0.ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ];
 </programlisting>
 
 Typically you’ll also want to set a default gateway and set of name
diff --git a/nixos/doc/manual/configuration/ipv6-config.xml b/nixos/doc/manual/configuration/ipv6-config.xml
index 6d9e0a164e9e..74a21e18ec3f 100644
--- a/nixos/doc/manual/configuration/ipv6-config.xml
+++ b/nixos/doc/manual/configuration/ipv6-config.xml
@@ -26,7 +26,7 @@ boot.kernel.sysctl."net.ipv6.conf.eth0.disable_ipv6" = true;
 DHCPv6. You can configure an interface manually:
 
 <programlisting>
-networking.interfaces.eth0.ip6 = [ { address = "fe00:aa:bb:cc::2"; prefixLength = 64; } ];
+networking.interfaces.eth0.ipv6.addresses = [ { address = "fe00:aa:bb:cc::2"; prefixLength = 64; } ];
 </programlisting>
 </para>
 
diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix
index bbe82066aa0c..6098b057a370 100644
--- a/nixos/doc/manual/default.nix
+++ b/nixos/doc/manual/default.nix
@@ -36,7 +36,7 @@ let
           package = args.package or (lib.attrByPath path (throw "Invalid package attribute path `${toString path}'") pkgs);
         in "<listitem>"
         + "<para><literal>pkgs.${name} (${package.meta.name})</literal>"
-        + lib.optionalString (!package.meta.evaluates) " <emphasis>[UNAVAILABLE]</emphasis>"
+        + lib.optionalString (!package.meta.available) " <emphasis>[UNAVAILABLE]</emphasis>"
         + ": ${package.meta.description or "???"}.</para>"
         + lib.optionalString (args ? comment) "\n<para>${args.comment}</para>"
         # Lots of `longDescription's break DocBook, so we just wrap them into <programlisting>
diff --git a/nixos/doc/manual/release-notes/rl-1803.xml b/nixos/doc/manual/release-notes/rl-1803.xml
index 2494e487da15..09d34b6f0356 100644
--- a/nixos/doc/manual/release-notes/rl-1803.xml
+++ b/nixos/doc/manual/release-notes/rl-1803.xml
@@ -261,10 +261,42 @@ following incompatible changes:</para>
   </listitem>
   <listitem>
     <para>
-      The option <option>services.xserver.desktopManager.default</option> is now <literal>none</literal> by default.
-      An assertion failure is thrown if WM's and DM's default are <literal>none</literal>.
-      To explicitly run a plain X session without and DM or WM, the newly introduced option <option>services.xserver.plainX</option>
-      must be set to true.
+      In the module <option>networking.interfaces.&lt;name&gt;</option> the
+      following options have been removed:
+      <itemizedlist>
+        <listitem>
+          <para><option>ipAddress</option></para>
+        </listitem>
+        <listitem>
+          <para><option>ipv6Address</option></para>
+        </listitem>
+        <listitem>
+          <para><option>prefixLength</option></para>
+        </listitem>
+        <listitem>
+          <para><option>ipv6PrefixLength</option></para>
+        </listitem>
+        <listitem>
+          <para><option>subnetMask</option></para>
+        </listitem>
+      </itemizedlist>
+      To assign static addresses to an interface the options
+      <option>ipv4.addresses</option> and <option>ipv6.addresses</option>
+      should be used instead.
+      The options <option>ip4</option> and <option>ip6</option> have been
+      renamed to <option>ipv4.addresses</option> <option>ipv6.addresses</option>
+      respectively.
+      The new options <option>ipv4.routes</option> and <option>ipv6.routes</option>
+      have been added to set up static routing.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+      The option <option>services.xserver.desktopManager.default</option> is now
+      <literal>none</literal> by default. An assertion failure is thrown if WM's
+      and DM's default are <literal>none</literal>.
+      To explicitly run a plain X session without and DM or WM, the newly
+      introduced option <option>services.xserver.plainX</option> must be set to true.
     </para>
   </listitem>
   <listitem>
diff --git a/nixos/lib/build-vms.nix b/nixos/lib/build-vms.nix
index 4685fe6914a2..e14105f5f011 100644
--- a/nixos/lib/build-vms.nix
+++ b/nixos/lib/build-vms.nix
@@ -51,7 +51,7 @@ rec {
             let
               interfacesNumbered = zipLists config.virtualisation.vlans (range 1 255);
               interfaces = flip map interfacesNumbered ({ fst, snd }:
-                nameValuePair "eth${toString snd}" { ip4 =
+                nameValuePair "eth${toString snd}" { ipv4.addresses =
                   [ { address = "192.168.${toString fst}.${toString m.snd}";
                       prefixLength = 24;
                   } ];
@@ -64,7 +64,7 @@ rec {
                   networking.interfaces = listToAttrs interfaces;
 
                   networking.primaryIPAddress =
-                    optionalString (interfaces != []) (head (head interfaces).value.ip4).address;
+                    optionalString (interfaces != []) (head (head interfaces).value.ipv4.addresses).address;
 
                   # Put the IP addresses of all VMs in this machine's
                   # /etc/hosts file.  If a machine has multiple
diff --git a/nixos/lib/make-disk-image.nix b/nixos/lib/make-disk-image.nix
index 8a3d8ed17701..b7a38760dd3a 100644
--- a/nixos/lib/make-disk-image.nix
+++ b/nixos/lib/make-disk-image.nix
@@ -84,7 +84,7 @@ let format' = format; in let
 
   nixpkgs = cleanSource pkgs.path;
 
-  channelSources = pkgs.runCommand "nixos-${config.system.nixosVersion}" {} ''
+  channelSources = pkgs.runCommand "nixos-${config.system.nixos.version}" {} ''
     mkdir -p $out
     cp -prd ${nixpkgs} $out/nixos
     chmod -R u+w $out/nixos
@@ -92,7 +92,7 @@ let format' = format; in let
       ln -s . $out/nixos/nixpkgs
     fi
     rm -rf $out/nixos/.git
-    echo -n ${config.system.nixosVersionSuffix} > $out/nixos/.version-suffix
+    echo -n ${config.system.nixos.versionSuffix} > $out/nixos/.version-suffix
   '';
 
   metaClosure = pkgs.writeText "meta" ''
diff --git a/nixos/modules/installer/cd-dvd/channel.nix b/nixos/modules/installer/cd-dvd/channel.nix
index ddb00f174d1a..4a1983167957 100644
--- a/nixos/modules/installer/cd-dvd/channel.nix
+++ b/nixos/modules/installer/cd-dvd/channel.nix
@@ -12,7 +12,7 @@ let
   # CD.  These are installed into the "nixos" channel of the root
   # user, as expected by nixos-rebuild/nixos-install. FIXME: merge
   # with make-channel.nix.
-  channelSources = pkgs.runCommand "nixos-${config.system.nixosVersion}"
+  channelSources = pkgs.runCommand "nixos-${config.system.nixos.version}"
     { }
     ''
       mkdir -p $out
@@ -21,7 +21,7 @@ let
       if [ ! -e $out/nixos/nixpkgs ]; then
         ln -s . $out/nixos/nixpkgs
       fi
-      echo -n ${config.system.nixosVersionSuffix} > $out/nixos/.version-suffix
+      echo -n ${config.system.nixos.versionSuffix} > $out/nixos/.version-suffix
     '';
 
 in
diff --git a/nixos/modules/installer/cd-dvd/installation-cd-base.nix b/nixos/modules/installer/cd-dvd/installation-cd-base.nix
index 2569860a098f..756c8751d00e 100644
--- a/nixos/modules/installer/cd-dvd/installation-cd-base.nix
+++ b/nixos/modules/installer/cd-dvd/installation-cd-base.nix
@@ -16,7 +16,7 @@ with lib;
     ];
 
   # ISO naming.
-  isoImage.isoName = "${config.isoImage.isoBaseName}-${config.system.nixosLabel}-${pkgs.stdenv.system}.iso";
+  isoImage.isoName = "${config.isoImage.isoBaseName}-${config.system.nixos.label}-${pkgs.stdenv.system}.iso";
 
   isoImage.volumeID = substring 0 11 "NIXOS_ISO";
 
diff --git a/nixos/modules/installer/cd-dvd/iso-image.nix b/nixos/modules/installer/cd-dvd/iso-image.nix
index a039f7fdcb6e..811449e9fe7e 100644
--- a/nixos/modules/installer/cd-dvd/iso-image.nix
+++ b/nixos/modules/installer/cd-dvd/iso-image.nix
@@ -39,31 +39,31 @@ let
     DEFAULT boot
 
     LABEL boot
-    MENU LABEL NixOS ${config.system.nixosLabel}${config.isoImage.appendToMenuLabel}
-    LINUX /boot/bzImage
+    MENU LABEL NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel}
+    LINUX /boot/${config.system.boot.loader.kernelFile}
     APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
-    INITRD /boot/initrd
+    INITRD /boot/${config.system.boot.loader.initrdFile}
 
     # A variant to boot with 'nomodeset'
     LABEL boot-nomodeset
-    MENU LABEL NixOS ${config.system.nixosVersion}${config.isoImage.appendToMenuLabel} (nomodeset)
-    LINUX /boot/bzImage
+    MENU LABEL NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel} (nomodeset)
+    LINUX /boot/${config.system.boot.loader.kernelFile}
     APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} nomodeset
-    INITRD /boot/initrd
+    INITRD /boot/${config.system.boot.loader.initrdFile}
 
     # A variant to boot with 'copytoram'
     LABEL boot-copytoram
-    MENU LABEL NixOS ${config.system.nixosVersion}${config.isoImage.appendToMenuLabel} (copytoram)
-    LINUX /boot/bzImage
+    MENU LABEL NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel} (copytoram)
+    LINUX /boot/${config.system.boot.loader.kernelFile}
     APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} copytoram
-    INITRD /boot/initrd
+    INITRD /boot/${config.system.boot.loader.initrdFile}
 
     # A variant to boot with verbose logging to the console
     LABEL boot-nomodeset
-    MENU LABEL NixOS ${config.system.nixosVersion}${config.isoImage.appendToMenuLabel} (debug)
-    LINUX /boot/bzImage
+    MENU LABEL NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel} (debug)
+    LINUX /boot/${config.system.boot.loader.kernelFile}
     APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} loglevel=7
-    INITRD /boot/initrd
+    INITRD /boot/${config.system.boot.loader.initrdFile}
   '';
 
   isolinuxMemtest86Entry = ''
@@ -82,35 +82,35 @@ let
     mkdir -p $out/loader/entries
 
     cat << EOF > $out/loader/entries/nixos-iso.conf
-    title NixOS ${config.system.nixosVersion}${config.isoImage.appendToMenuLabel}
-    linux /boot/bzImage
-    initrd /boot/initrd
+    title NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel}
+    linux /boot/${config.system.boot.loader.kernelFile}
+    initrd /boot/${config.system.boot.loader.initrdFile}
     options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
     EOF
 
     # A variant to boot with 'nomodeset'
     cat << EOF > $out/loader/entries/nixos-iso-nomodeset.conf
-    title NixOS ${config.system.nixosVersion}${config.isoImage.appendToMenuLabel}
+    title NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel}
     version nomodeset
-    linux /boot/bzImage
-    initrd /boot/initrd
+    linux /boot/${config.system.boot.loader.kernelFile}
+    initrd /boot/${config.system.boot.loader.initrdFile}
     options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} nomodeset
     EOF
 
     # A variant to boot with 'copytoram'
     cat << EOF > $out/loader/entries/nixos-iso-copytoram.conf
-    title NixOS ${config.system.nixosVersion}${config.isoImage.appendToMenuLabel}
+    title NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel}
     version copytoram
-    linux /boot/bzImage
-    initrd /boot/initrd
+    linux /boot/${config.system.boot.loader.kernelFile}
+    initrd /boot/${config.system.boot.loader.initrdFile}
     options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} copytoram
     EOF
 
     # A variant to boot with verbose logging to the console
     cat << EOF > $out/loader/entries/nixos-iso-debug.conf
-    title NixOS ${config.system.nixosVersion}${config.isoImage.appendToMenuLabel} (debug)
-    linux /boot/bzImage
-    initrd /boot/initrd
+    title NixOS ${config.system.nixos.label}${config.isoImage.appendToMenuLabel} (debug)
+    linux /boot/${config.system.boot.loader.kernelFile}
+    initrd /boot/${config.system.boot.loader.initrdFile}
     options init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} loglevel=7
     EOF
 
@@ -127,8 +127,8 @@ let
       mkdir ./contents && cd ./contents
       cp -rp "${efiDir}"/* .
       mkdir ./boot
-      cp -p "${config.boot.kernelPackages.kernel}/bzImage" \
-        "${config.system.build.initialRamdisk}/initrd" ./boot/
+      cp -p "${config.boot.kernelPackages.kernel}/${config.system.boot.loader.kernelFile}" \
+        "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}" ./boot/
       touch --date=@0 ./*
 
       usage_size=$(du -sb --apparent-size . | tr -cd '[:digit:]')
@@ -346,11 +346,11 @@ in
           };
           target = "/isolinux/isolinux.cfg";
         }
-        { source = config.boot.kernelPackages.kernel + "/bzImage";
-          target = "/boot/bzImage";
+        { source = config.boot.kernelPackages.kernel + "/" + config.system.boot.loader.kernelFile;
+          target = "/boot/" + config.system.boot.loader.kernelFile;
         }
-        { source = config.system.build.initialRamdisk + "/initrd";
-          target = "/boot/initrd";
+        { source = config.system.build.initialRamdisk + "/" + config.system.boot.loader.initrdFile;
+          target = "/boot/" + config.system.boot.loader.initrdFile;
         }
         { source = config.system.build.squashfsStore;
           target = "/nix-store.squashfs";
@@ -361,7 +361,7 @@ in
         { source = config.isoImage.splashImage;
           target = "/isolinux/background.png";
         }
-        { source = pkgs.writeText "version" config.system.nixosVersion;
+        { source = pkgs.writeText "version" config.system.nixos.label;
           target = "/version.txt";
         }
       ] ++ optionals config.isoImage.makeEfiBootable [
diff --git a/nixos/modules/installer/cd-dvd/system-tarball.nix b/nixos/modules/installer/cd-dvd/system-tarball.nix
index 1962a1959ead..e72d4a5b4910 100644
--- a/nixos/modules/installer/cd-dvd/system-tarball.nix
+++ b/nixos/modules/installer/cd-dvd/system-tarball.nix
@@ -8,7 +8,7 @@ with lib;
 
 let
 
-  versionFile = pkgs.writeText "nixos-version" config.system.nixosVersion;
+  versionFile = pkgs.writeText "nixos-label" config.system.nixos.label;
 
 in
 
@@ -58,8 +58,8 @@ in
     # Individual files to be included on the CD, outside of the Nix
     # store on the CD.
     tarball.contents =
-      [ { source = config.system.build.initialRamdisk + "/initrd";
-          target = "/boot/initrd";
+      [ { source = config.system.build.initialRamdisk + "/" + config.system.boot.loader.initrdFile;
+          target = "/boot/" + config.system.boot.loader.initrdFile;
         }
         { source = versionFile;
           target = "/nixos-version.txt";
diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl
index 7c737e84de0a..a82ee63fd0cd 100644
--- a/nixos/modules/installer/tools/nixos-generate-config.pl
+++ b/nixos/modules/installer/tools/nixos-generate-config.pl
@@ -625,7 +625,7 @@ $bootLoaderConfig
   # compatible, in order to avoid breaking some software such as database
   # servers. You should change this only after NixOS release notes say you
   # should.
-  system.stateVersion = "${\(qw(@nixosRelease@))}"; # Did you read the comment?
+  system.stateVersion = "${\(qw(@release@))}"; # Did you read the comment?
 
 }
 EOF
diff --git a/nixos/modules/installer/tools/nixos-version.sh b/nixos/modules/installer/tools/nixos-version.sh
index 77a1b458a342..190c49a33ec6 100644
--- a/nixos/modules/installer/tools/nixos-version.sh
+++ b/nixos/modules/installer/tools/nixos-version.sh
@@ -6,9 +6,9 @@ case "$1" in
     exit 1
     ;;
   --hash|--revision)
-    echo "@nixosRevision@"
+    echo "@revision@"
     ;;
   *)
-    echo "@nixosVersion@ (@nixosCodeName@)"
+    echo "@version@ (@codeName@)"
     ;;
 esac
diff --git a/nixos/modules/installer/tools/tools.nix b/nixos/modules/installer/tools/tools.nix
index a3bae78c0ffc..eab5f1147667 100644
--- a/nixos/modules/installer/tools/tools.nix
+++ b/nixos/modules/installer/tools/tools.nix
@@ -55,7 +55,7 @@ let
     src = ./nixos-generate-config.pl;
     path = [ pkgs.btrfs-progs ];
     perl = "${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl";
-    inherit (config.system) nixosRelease;
+    inherit (config.system.nixos) release;
   };
 
   nixos-option = makeProg {
@@ -66,7 +66,7 @@ let
   nixos-version = makeProg {
     name = "nixos-version";
     src = ./nixos-version.sh;
-    inherit (config.system) nixosVersion nixosCodeName nixosRevision;
+    inherit (config.system.nixos) version codeName revision;
   };
 
 in
diff --git a/nixos/modules/misc/label.nix b/nixos/modules/misc/label.nix
new file mode 100644
index 000000000000..250914e8f82e
--- /dev/null
+++ b/nixos/modules/misc/label.nix
@@ -0,0 +1,72 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.system.nixos;
+in
+
+{
+
+  options.system = {
+
+    nixos.label = mkOption {
+      type = types.str;
+      description = ''
+        NixOS version name to be used in the names of generated
+        outputs and boot labels.
+
+        If you ever wanted to influence the labels in your GRUB menu,
+        this is the option for you.
+
+        The default is <option>system.nixos.tags</option> separated by
+        "-" + "-" + <envar>NIXOS_LABEL_VERSION</envar> environment
+        variable (defaults to the value of
+        <option>system.nixos.version</option>).
+
+        Can be overriden by setting <envar>NIXOS_LABEL</envar>.
+
+        Useful for not loosing track of configurations built from different
+        nixos branches/revisions, e.g.:
+
+        <screen>
+        #!/bin/sh
+        today=`date +%Y%m%d`
+        branch=`(cd nixpkgs ; git branch 2>/dev/null | sed -n '/^\* / { s|^\* ||; p; }')`
+        revision=`(cd nixpkgs ; git rev-parse HEAD)`
+        export NIXOS_LABEL_VERSION="$today.$branch-''${revision:0:7}"
+        nixos-rebuild switch</screen>
+      '';
+    };
+
+    nixos.tags = mkOption {
+      type = types.listOf types.str;
+      default = [];
+      example = [ "with-xen" ];
+      description = ''
+        Strings to prefix to the default
+        <option>system.nixos.label</option>.
+
+        Useful for not loosing track of configurations built with
+        different options, e.g.:
+
+        <screen>
+        {
+          system.nixos.tags = [ "with-xen" ];
+          virtualisation.xen.enable = true;
+        }
+        </screen>
+      '';
+    };
+
+  };
+
+  config = {
+    # This is set here rather than up there so that changing it would
+    # not rebuild the manual
+    system.nixos.label = mkDefault (maybeEnv "NIXOS_LABEL"
+                                             (concatStringsSep "-" (sort (x: y: x < y) cfg.tags)
+                                             + "-" + maybeEnv "NIXOS_LABEL_VERSION" cfg.version));
+  };
+
+}
diff --git a/nixos/modules/misc/version.nix b/nixos/modules/misc/version.nix
index 48cde2ebbc8a..6af584250a70 100644
--- a/nixos/modules/misc/version.nix
+++ b/nixos/modules/misc/version.nix
@@ -3,7 +3,7 @@
 with lib;
 
 let
-  cfg = config.system;
+  cfg = config.system.nixos;
 
   releaseFile  = "${toString pkgs.path}/.version";
   suffixFile   = "${toString pkgs.path}/.version-suffix";
@@ -16,51 +16,27 @@ in
 
   options.system = {
 
-    stateVersion = mkOption {
-      type = types.str;
-      default = cfg.nixosRelease;
-      description = ''
-        Every once in a while, a new NixOS release may change
-        configuration defaults in a way incompatible with stateful
-        data. For instance, if the default version of PostgreSQL
-        changes, the new version will probably be unable to read your
-        existing databases. To prevent such breakage, you can set the
-        value of this option to the NixOS release with which you want
-        to be compatible. The effect is that NixOS will option
-        defaults corresponding to the specified release (such as using
-        an older version of PostgreSQL).
-      '';
-    };
-
-    nixosLabel = mkOption {
-      type = types.str;
-      description = ''
-        Label to be used in the names of generated outputs and boot
-        labels.
-      '';
-    };
-
-    nixosVersion = mkOption {
+    nixos.version = mkOption {
       internal = true;
       type = types.str;
       description = "The full NixOS version (e.g. <literal>16.03.1160.f2d4ee1</literal>).";
     };
 
-    nixosRelease = mkOption {
+    nixos.release = mkOption {
       readOnly = true;
       type = types.str;
       default = fileContents releaseFile;
       description = "The NixOS release (e.g. <literal>16.03</literal>).";
     };
 
-    nixosVersionSuffix = mkOption {
+    nixos.versionSuffix = mkOption {
       internal = true;
       type = types.str;
       default = if pathExists suffixFile then fileContents suffixFile else "pre-git";
       description = "The NixOS version suffix (e.g. <literal>1160.f2d4ee1</literal>).";
     };
 
-    nixosRevision = mkOption {
+    nixos.revision = mkOption {
       internal = true;
       type = types.str;
       default = if pathIsDirectory gitRepo then commitIdFromGitRepo gitRepo
@@ -69,12 +45,28 @@ in
       description = "The Git revision from which this NixOS configuration was built.";
     };
 
-    nixosCodeName = mkOption {
+    nixos.codeName = mkOption {
       readOnly = true;
       type = types.str;
       description = "The NixOS release code name (e.g. <literal>Emu</literal>).";
     };
 
+    stateVersion = mkOption {
+      type = types.str;
+      default = cfg.release;
+      description = ''
+        Every once in a while, a new NixOS release may change
+        configuration defaults in a way incompatible with stateful
+        data. For instance, if the default version of PostgreSQL
+        changes, the new version will probably be unable to read your
+        existing databases. To prevent such breakage, you can set the
+        value of this option to the NixOS release with which you want
+        to be compatible. The effect is that NixOS will option
+        defaults corresponding to the specified release (such as using
+        an older version of PostgreSQL).
+      '';
+    };
+
     defaultChannel = mkOption {
       internal = true;
       type = types.str;
@@ -86,16 +78,15 @@ in
 
   config = {
 
-    system = {
+    system.nixos = {
       # These defaults are set here rather than up there so that
       # changing them would not rebuild the manual
-      nixosLabel   = mkDefault cfg.nixosVersion;
-      nixosVersion = mkDefault (cfg.nixosRelease + cfg.nixosVersionSuffix);
-      nixosRevision      = mkIf (pathIsDirectory gitRepo) (mkDefault            gitCommitId);
-      nixosVersionSuffix = mkIf (pathIsDirectory gitRepo) (mkDefault (".git." + gitCommitId));
+      version = mkDefault (cfg.release + cfg.versionSuffix);
+      revision      = mkIf (pathIsDirectory gitRepo) (mkDefault            gitCommitId);
+      versionSuffix = mkIf (pathIsDirectory gitRepo) (mkDefault (".git." + gitCommitId));
 
       # Note: code names must only increase in alphabetical order.
-      nixosCodeName = "Impala";
+      codeName = "Impala";
     };
 
     # Generate /etc/os-release.  See
@@ -105,10 +96,10 @@ in
       ''
         NAME=NixOS
         ID=nixos
-        VERSION="${config.system.nixosVersion} (${config.system.nixosCodeName})"
-        VERSION_CODENAME=${toLower config.system.nixosCodeName}
-        VERSION_ID="${config.system.nixosVersion}"
-        PRETTY_NAME="NixOS ${config.system.nixosVersion} (${config.system.nixosCodeName})"
+        VERSION="${cfg.version} (${cfg.codeName})"
+        VERSION_CODENAME=${toLower cfg.codeName}
+        VERSION_ID="${cfg.version}"
+        PRETTY_NAME="NixOS ${cfg.version} (${cfg.codeName})"
         HOME_URL="https://nixos.org/"
         SUPPORT_URL="https://nixos.org/nixos/support.html"
         BUG_REPORT_URL="https://github.com/NixOS/nixpkgs/issues"
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 01bd2960517b..a3f820a35a10 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -60,6 +60,7 @@
   ./misc/extra-arguments.nix
   ./misc/ids.nix
   ./misc/lib.nix
+  ./misc/label.nix
   ./misc/locate.nix
   ./misc/meta.nix
   ./misc/nixpkgs.nix
diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix
index 710387ebc1d6..da83baed3719 100644
--- a/nixos/modules/rename.nix
+++ b/nixos/modules/rename.nix
@@ -189,6 +189,14 @@ with lib;
     # Profile splitting
     (mkRenamedOptionModule [ "virtualization" "growPartition" ] [ "boot" "growPartition" ])
 
+    # misc/version.nix
+    (mkRenamedOptionModule [ "config" "system" "nixosVersion" ] [ "config" "system" "nixos" "version" ])
+    (mkRenamedOptionModule [ "config" "system" "nixosRelease" ] [ "config" "system" "nixos" "release" ])
+    (mkRenamedOptionModule [ "config" "system" "nixosVersionSuffix" ] [ "config" "system" "nixos" "versionSuffix" ])
+    (mkRenamedOptionModule [ "config" "system" "nixosRevision" ] [ "config" "system" "nixos" "revision" ])
+    (mkRenamedOptionModule [ "config" "system" "nixosCodeName" ] [ "config" "system" "nixos" "codeName" ])
+    (mkRenamedOptionModule [ "config" "system" "nixosLabel" ] [ "config" "system" "nixos" "label" ])
+
     # Options that are obsolete and have no replacement.
     (mkRemovedOptionModule [ "boot" "initrd" "luks" "enable" ] "")
     (mkRemovedOptionModule [ "programs" "bash" "enable" ] "")
diff --git a/nixos/modules/services/misc/nixos-manual.nix b/nixos/modules/services/misc/nixos-manual.nix
index 41cadb4a6de0..5d0f2abd13a9 100644
--- a/nixos/modules/services/misc/nixos-manual.nix
+++ b/nixos/modules/services/misc/nixos-manual.nix
@@ -16,10 +16,10 @@ let
     It isn't perfect, but it seems to cover a vast majority of use cases.
     Caveat: even if the package is reached by a different means,
     the path above will be shown and not e.g. `${config.services.foo.package}`. */
-  manual = import ../../../doc/manual {
+  manual = import ../../../doc/manual rec {
     inherit pkgs config;
-    version = config.system.nixosRelease;
-    revision = "release-${config.system.nixosRelease}";
+    version = config.system.nixos.release;
+    revision = "release-${version}";
     options =
       let
         scrubbedEval = evalModules {
diff --git a/nixos/modules/services/misc/ssm-agent.nix b/nixos/modules/services/misc/ssm-agent.nix
index c1e1f0903539..a57fbca86fb6 100644
--- a/nixos/modules/services/misc/ssm-agent.nix
+++ b/nixos/modules/services/misc/ssm-agent.nix
@@ -12,7 +12,7 @@ let
 
     case "$1" in
       -i) echo "nixos";;
-      -r) echo "${config.system.nixosVersion}";;
+      -r) echo "${config.system.nixos.version}";;
     esac
   '';
 in {
diff --git a/nixos/modules/services/networking/dhcpcd.nix b/nixos/modules/services/networking/dhcpcd.nix
index d283c7624335..d10b72ecf058 100644
--- a/nixos/modules/services/networking/dhcpcd.nix
+++ b/nixos/modules/services/networking/dhcpcd.nix
@@ -16,7 +16,7 @@ let
   # Don't start dhcpcd on explicitly configured interfaces or on
   # interfaces that are part of a bridge, bond or sit device.
   ignoredInterfaces =
-    map (i: i.name) (filter (i: if i.useDHCP != null then !i.useDHCP else i.ip4 != [ ] || i.ipAddress != null) interfaces)
+    map (i: i.name) (filter (i: if i.useDHCP != null then !i.useDHCP else i.ipv4.addresses != [ ]) interfaces)
     ++ mapAttrsToList (i: _: i) config.networking.sits
     ++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bridges))
     ++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.vswitches))
diff --git a/nixos/modules/services/security/hologram-agent.nix b/nixos/modules/services/security/hologram-agent.nix
index 6c53a2df6306..39ed506f7617 100644
--- a/nixos/modules/services/security/hologram-agent.nix
+++ b/nixos/modules/services/security/hologram-agent.nix
@@ -35,10 +35,9 @@ in {
   config = mkIf cfg.enable {
     boot.kernelModules = [ "dummy" ];
 
-    networking.interfaces.dummy0 = {
-      ipAddress = "169.254.169.254";
-      prefixLength = 32;
-    };
+    networking.interfaces.dummy0.ipv4.addresses = [
+      { address = "169.254.169.254"; prefixLength = 32; }
+    ];
 
     systemd.services.hologram-agent = {
       description = "Provide EC2 instance credentials to machines outside of EC2";
diff --git a/nixos/modules/services/ttys/agetty.nix b/nixos/modules/services/ttys/agetty.nix
index 3429397d2cc2..b50de496e975 100644
--- a/nixos/modules/services/ttys/agetty.nix
+++ b/nixos/modules/services/ttys/agetty.nix
@@ -64,8 +64,8 @@ in
 
   config = {
     # Note: this is set here rather than up there so that changing
-    # nixosLabel would not rebuild manual pages
-    services.mingetty.greetingLine = mkDefault ''<<< Welcome to NixOS ${config.system.nixosLabel} (\m) - \l >>>'';
+    # nixos.label would not rebuild manual pages
+    services.mingetty.greetingLine = mkDefault ''<<< Welcome to NixOS ${config.system.nixos.label} (\m) - \l >>>'';
 
     systemd.services."getty@" =
       { serviceConfig.ExecStart = [
diff --git a/nixos/modules/system/activation/top-level.nix b/nixos/modules/system/activation/top-level.nix
index 0c50241f2edf..091a2e412eed 100644
--- a/nixos/modules/system/activation/top-level.nix
+++ b/nixos/modules/system/activation/top-level.nix
@@ -30,6 +30,8 @@ let
     let
       kernelPath = "${config.boot.kernelPackages.kernel}/" +
         "${config.system.boot.loader.kernelFile}";
+      initrdPath = "${config.system.build.initialRamdisk}/" +
+        "${config.system.boot.loader.initrdFile}";
     in ''
       mkdir $out
 
@@ -50,7 +52,7 @@ let
 
         echo -n "$kernelParams" > $out/kernel-params
 
-        ln -s ${config.system.build.initialRamdisk}/initrd $out/initrd
+        ln -s ${initrdPath} $out/initrd
 
         ln -s ${config.system.build.initialRamdiskSecretAppender}/bin/append-initrd-secrets $out
 
@@ -106,7 +108,7 @@ let
     if [] == failed then pkgs.stdenvNoCC.mkDerivation {
       name = let hn = config.networking.hostName;
                  nn = if (hn != "") then hn else "unnamed";
-          in "nixos-system-${nn}-${config.system.nixosLabel}";
+          in "nixos-system-${nn}-${config.system.nixos.label}";
       preferLocalBuild = true;
       allowSubstitutes = false;
       buildCommand = systemBuilder;
@@ -120,7 +122,7 @@ let
         config.system.build.installBootLoader
         or "echo 'Warning: do not know how to make this configuration bootable; please enable a boot loader.' 1>&2; true";
       activationScript = config.system.activationScripts.script;
-      nixosLabel = config.system.nixosLabel;
+      nixosLabel = config.system.nixos.label;
 
       configurationName = config.boot.loader.grub.configurationName;
 
@@ -179,6 +181,15 @@ in
       '';
     };
 
+    system.boot.loader.initrdFile = mkOption {
+      internal = true;
+      default = "initrd";
+      type = types.str;
+      description = ''
+        Name of the initrd file to be passed to the bootloader.
+      '';
+    };
+
     system.copySystemConfiguration = mkOption {
       type = types.bool;
       default = false;
diff --git a/nixos/modules/system/boot/plymouth.nix b/nixos/modules/system/boot/plymouth.nix
index e78fdf1311d3..f8fb8a64cb9b 100644
--- a/nixos/modules/system/boot/plymouth.nix
+++ b/nixos/modules/system/boot/plymouth.nix
@@ -10,7 +10,7 @@ let
 
   breezePlymouth = pkgs.breeze-plymouth.override {
     nixosBranding = true;
-    nixosVersion = config.system.nixosRelease;
+    nixosVersion = config.system.nixos.release;
   };
 
   themesEnv = pkgs.buildEnv {
diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix
index 63d07832d105..66732ce7732e 100644
--- a/nixos/modules/tasks/network-interfaces-scripted.nix
+++ b/nixos/modules/tasks/network-interfaces-scripted.nix
@@ -20,14 +20,8 @@ let
     "sys-subsystem-net-devices-${escapeSystemdPath interface}.device";
 
   interfaceIps = i:
-    i.ip4 ++ optionals cfg.enableIPv6 i.ip6
-    ++ optional (i.ipAddress != null) {
-      address = i.ipAddress;
-      prefixLength = i.prefixLength;
-    } ++ optional (cfg.enableIPv6 && i.ipv6Address != null) {
-      address = i.ipv6Address;
-      prefixLength = i.ipv6PrefixLength;
-    };
+    i.ipv4.addresses
+    ++ optionals cfg.enableIPv6 i.ipv6.addresses;
 
   destroyBond = i: ''
     while true; do
@@ -185,33 +179,58 @@ let
             path = [ pkgs.iproute ];
             script =
               ''
-                # FIXME: shouldn't this be done in network-link?
-                echo "bringing up interface..."
-                ip link set "${i.name}" up
-
                 state="/run/nixos/network/addresses/${i.name}"
+                mkdir -p $(dirname "$state")
 
+                ${flip concatMapStrings ips (ip:
+                  let
+                    cidr = "${ip.address}/${toString ip.prefixLength}";
+                  in
+                  ''
+                    echo "${cidr}" >> $state
+                    echo -n "adding address ${cidr}... "
+                    if out=$(ip addr add "${cidr}" dev "${i.name}" 2>&1); then
+                      echo "done"
+                    elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then
+                      echo "failed"
+                      exit 1
+                    fi
+                  ''
+                )}
+
+                state="/run/nixos/network/routes/${i.name}"
                 mkdir -p $(dirname "$state")
 
-              '' + flip concatMapStrings (ips) (ip:
-                let
-                  address = "${ip.address}/${toString ip.prefixLength}";
-                in
-                ''
-                  echo "${address}" >> $state
-                  if out=$(ip addr add "${address}" dev "${i.name}" 2>&1); then
-                    echo "added ip ${address}"
-                  elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then
-                    echo "failed to add ${address}"
-                    exit 1
-                  fi
-                '');
+                ${flip concatMapStrings (i.ipv4.routes ++ i.ipv6.routes) (route:
+                  let
+                    cidr = "${route.address}/${toString route.prefixLength}";
+                    via = optionalString (route.via != null) ''via "${route.via}"'';
+                    options = concatStrings (mapAttrsToList (name: val: "${name} ${val} ") route.options);
+                  in
+                  ''
+                     echo "${cidr}" >> $state
+                     echo -n "adding route ${cidr}... "
+                     if out=$(ip route add "${cidr}" ${options} ${via} dev "${i.name}" 2>&1); then
+                       echo "done"
+                     elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then
+                       echo "failed"
+                       exit 1
+                     fi
+                  ''
+                )}
+              '';
             preStop = ''
+              state="/run/nixos/network/routes/${i.name}"
+              while read cidr; do
+                echo -n "deleting route $cidr... "
+                ip route del "$cidr" dev "${i.name}" >/dev/null 2>&1 && echo "done" || echo "failed"
+              done < "$state"
+              rm -f "$state"
+
               state="/run/nixos/network/addresses/${i.name}"
-              while read address; do
-                echo -n "deleting $address..."
-                ip addr del "$address" dev "${i.name}" >/dev/null 2>&1 || echo -n " Failed"
-                echo ""
+              while read cidr; do
+                echo -n "deleting address $cidr... "
+                ip addr del "$cidr" dev "${i.name}" >/dev/null 2>&1 && echo "done" || echo "failed"
               done < "$state"
               rm -f "$state"
             '';
diff --git a/nixos/modules/tasks/network-interfaces-systemd.nix b/nixos/modules/tasks/network-interfaces-systemd.nix
index be7f52a76def..c640e886fca8 100644
--- a/nixos/modules/tasks/network-interfaces-systemd.nix
+++ b/nixos/modules/tasks/network-interfaces-systemd.nix
@@ -9,14 +9,8 @@ let
   interfaces = attrValues cfg.interfaces;
 
   interfaceIps = i:
-    i.ip4 ++ optionals cfg.enableIPv6 i.ip6
-    ++ optional (i.ipAddress != null) {
-      address = i.ipAddress;
-      prefixLength = i.prefixLength;
-    } ++ optional (cfg.enableIPv6 && i.ipv6Address != null) {
-      address = i.ipv6Address;
-      prefixLength = i.ipv6PrefixLength;
-    };
+    i.ipv4.addresses
+    ++ optionals cfg.enableIPv6 i.ipv6.addresses;
 
   dhcpStr = useDHCP: if useDHCP == true || useDHCP == null then "both" else "none";
 
diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
index f80c5045c07d..5036b701bd86 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -1,4 +1,4 @@
-{ config, lib, pkgs, utils, stdenv, ... }:
+{ config, options, lib, pkgs, utils, stdenv, ... }:
 
 with lib;
 with utils;
@@ -101,7 +101,7 @@ let
         address = mkOption {
           type = types.str;
           description = ''
-            IPv${toString v} address of the interface.  Leave empty to configure the
+            IPv${toString v} address of the interface. Leave empty to configure the
             interface using DHCP.
           '';
         };
@@ -116,6 +116,40 @@ let
       };
     };
 
+  routeOpts = v:
+  { options = {
+      address = mkOption {
+        type = types.str;
+        description = "IPv${toString v} address of the network.";
+      };
+
+      prefixLength = mkOption {
+        type = types.addCheck types.int (n: n >= 0 && n <= (if v == 4 then 32 else 128));
+        description = ''
+          Subnet mask of the network, specified as the number of
+          bits in the prefix (<literal>${if v == 4 then "24" else "64"}</literal>).
+        '';
+      };
+
+      via = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        description = "IPv${toString v} address of the next hop.";
+      };
+
+      options = mkOption {
+        type = types.attrsOf types.str;
+        default = { };
+        example = { mtu = "1492"; window = "524288"; };
+        description = ''
+          Other route options. See the symbol <literal>OPTION</literal>
+          in the <literal>ip-route(8)</literal> manual page for the details.
+        '';
+      };
+
+    };
+  };
+
   gatewayCoerce = address: { inherit address; };
 
   gatewayOpts = { ... }: {
@@ -148,7 +182,6 @@ let
   interfaceOpts = { name, ... }: {
 
     options = {
-
       name = mkOption {
         example = "eth0";
         type = types.str;
@@ -175,7 +208,7 @@ let
         '';
       };
 
-      ip4 = mkOption {
+      ipv4.addresses = mkOption {
         default = [ ];
         example = [
           { address = "10.0.0.1"; prefixLength = 16; }
@@ -187,7 +220,7 @@ let
         '';
       };
 
-      ip6 = mkOption {
+      ipv6.addresses = mkOption {
         default = [ ];
         example = [
           { address = "fdfd:b3f0:482::1"; prefixLength = 48; }
@@ -199,50 +232,27 @@ let
         '';
       };
 
-      ipAddress = mkOption {
-        default = null;
-        example = "10.0.0.1";
-        type = types.nullOr types.str;
-        description = ''
-          IP address of the interface.  Leave empty to configure the
-          interface using DHCP.
-        '';
-      };
-
-      prefixLength = mkOption {
-        default = null;
-        example = 24;
-        type = types.nullOr types.int;
-        description = ''
-          Subnet mask of the interface, specified as the number of
-          bits in the prefix (<literal>24</literal>).
-        '';
-      };
-
-      subnetMask = mkOption {
-        default = null;
-        description = ''
-          Defunct, supply the prefix length instead.
-        '';
-      };
-
-      ipv6Address = mkOption {
-        default = null;
-        example = "2001:1470:fffd:2098::e006";
-        type = types.nullOr types.str;
+      ipv4.routes = mkOption {
+        default = [];
+        example = [
+          { address = "10.0.0.0"; prefixLength = 16; }
+          { address = "192.168.2.0"; prefixLength = 24; via = "192.168.1.1"; }
+        ];
+        type = with types; listOf (submodule (routeOpts 4));
         description = ''
-          IPv6 address of the interface.  Leave empty to configure the
-          interface using NDP.
+          List of extra IPv4 static routes that will be assigned to the interface.
         '';
       };
 
-      ipv6PrefixLength = mkOption {
-        default = 64;
-        example = 64;
-        type = types.int;
+      ipv6.routes = mkOption {
+        default = [];
+        example = [
+          { address = "fdfd:b3f0::"; prefixLength = 48; }
+          { address = "2001:1470:fffd:2098::"; prefixLength = 64; via = "fdfd:b3f0::1"; }
+        ];
+        type = with types; listOf (submodule (routeOpts 6));
         description = ''
-          Subnet mask of the interface, specified as the number of
-          bits in the prefix (<literal>64</literal>).
+          List of extra IPv6 static routes that will be assigned to the interface.
         '';
       };
 
@@ -317,6 +327,32 @@ let
       name = mkDefault name;
     };
 
+    # Renamed or removed options
+    imports =
+      let
+        defined = x: x != "_mkMergedOptionModule";
+      in [
+        (mkRenamedOptionModule [ "ip4" ] [ "ipv4" "addresses"])
+        (mkRenamedOptionModule [ "ip6" ] [ "ipv6" "addresses"])
+        (mkRemovedOptionModule [ "subnetMask" ] ''
+          Supply a prefix length instead; use option
+          networking.interfaces.<name>.ipv{4,6}.addresses'')
+        (mkMergedOptionModule
+          [ [ "ipAddress" ] [ "prefixLength" ] ]
+          [ "ipv4" "addresses" ]
+          (cfg: with cfg;
+            optional (defined ipAddress && defined prefixLength)
+            { address = ipAddress; prefixLength = prefixLength; }))
+        (mkMergedOptionModule
+          [ [ "ipv6Address" ] [ "ipv6PrefixLength" ] ]
+          [ "ipv6" "addresses" ]
+          (cfg: with cfg;
+            optional (defined ipv6Address && defined ipv6PrefixLength)
+            { address = ipv6Address; prefixLength = ipv6PrefixLength; }))
+
+        ({ options.warnings = options.warnings; })
+      ];
+
   };
 
   hexChars = stringToCharacters "0123456789abcdef";
@@ -453,7 +489,7 @@ in
     networking.interfaces = mkOption {
       default = {};
       example =
-        { eth0.ip4 = [ {
+        { eth0.ipv4 = [ {
             address = "131.211.84.78";
             prefixLength = 25;
           } ];
@@ -932,13 +968,10 @@ in
 
   config = {
 
+    warnings = concatMap (i: i.warnings) interfaces;
+
     assertions =
       (flip map interfaces (i: {
-        assertion = i.subnetMask == null;
-        message = ''
-          The networking.interfaces."${i.name}".subnetMask option is defunct. Use prefixLength instead.
-        '';
-      })) ++ (flip map interfaces (i: {
         # With the linux kernel, interface name length is limited by IFNAMSIZ
         # to 16 bytes, including the trailing null byte.
         # See include/linux/if.h in the kernel sources
@@ -947,7 +980,7 @@ in
           The name of networking.interfaces."${i.name}" is too long, it needs to be less than 16 characters.
         '';
       })) ++ (flip map slaveIfs (i: {
-        assertion = i.ip4 == [ ] && i.ipAddress == null && i.ip6 == [ ] && i.ipv6Address == null;
+        assertion = i.ipv4.addresses == [ ] && i.ipv6.addresses == [ ];
         message = ''
           The networking.interfaces."${i.name}" must not have any defined ips when it is a slave.
         '';
@@ -1089,6 +1122,9 @@ in
           '' + optionalString (i.mtu != null) ''
             echo "setting MTU to ${toString i.mtu}..."
             ip link set "${i.name}" mtu "${toString i.mtu}"
+          '' + ''
+            echo -n "bringing up interface... "
+            ip link set "${i.name}" up && echo "done" || (echo "failed"; exit 1)
           '';
       })));
 
diff --git a/nixos/modules/virtualisation/brightbox-image.nix b/nixos/modules/virtualisation/brightbox-image.nix
index 08bbcfd9d7c2..39a655b4c104 100644
--- a/nixos/modules/virtualisation/brightbox-image.nix
+++ b/nixos/modules/virtualisation/brightbox-image.nix
@@ -26,7 +26,7 @@ in
               rm $diskImageBase
               popd
             '';
-          diskImageBase = "nixos-image-${config.system.nixosLabel}-${pkgs.stdenv.system}.raw";
+          diskImageBase = "nixos-image-${config.system.nixos.label}-${pkgs.stdenv.system}.raw";
           buildInputs = [ pkgs.utillinux pkgs.perl ];
           exportReferencesGraph =
             [ "closure" config.system.build.toplevel ];
diff --git a/nixos/modules/virtualisation/google-compute-image.nix b/nixos/modules/virtualisation/google-compute-image.nix
index 2fb38059b261..155a33b3bb37 100644
--- a/nixos/modules/virtualisation/google-compute-image.nix
+++ b/nixos/modules/virtualisation/google-compute-image.nix
@@ -14,7 +14,7 @@ in
       PATH=$PATH:${pkgs.stdenv.lib.makeBinPath [ pkgs.gnutar pkgs.gzip ]}
       pushd $out
       mv $diskImage disk.raw
-      tar -Szcf nixos-image-${config.system.nixosLabel}-${pkgs.stdenv.system}.raw.tar.gz disk.raw
+      tar -Szcf nixos-image-${config.system.nixos.label}-${pkgs.stdenv.system}.raw.tar.gz disk.raw
       rm $out/disk.raw
       popd
     '';
diff --git a/nixos/modules/virtualisation/virtualbox-host.nix b/nixos/modules/virtualisation/virtualbox-host.nix
index bb0c38bd4eb8..7413e12c8f3d 100644
--- a/nixos/modules/virtualisation/virtualbox-host.nix
+++ b/nixos/modules/virtualisation/virtualbox-host.nix
@@ -124,7 +124,7 @@ in
           '';
       };
 
-    networking.interfaces.vboxnet0.ip4 = [ { address = "192.168.56.1"; prefixLength = 24; } ];
+    networking.interfaces.vboxnet0.ipv4.addresses = [{ address = "192.168.56.1"; prefixLength = 24; }];
     # Make sure NetworkManager won't assume this interface being up
     # means we have internet access.
     networking.networkmanager.unmanaged = ["vboxnet0"];
diff --git a/nixos/modules/virtualisation/virtualbox-image.nix b/nixos/modules/virtualisation/virtualbox-image.nix
index a544403e6bed..64f145f77ca3 100644
--- a/nixos/modules/virtualisation/virtualbox-image.nix
+++ b/nixos/modules/virtualisation/virtualbox-image.nix
@@ -22,7 +22,7 @@ in {
 
   config = {
     system.build.virtualBoxOVA = import ../../lib/make-disk-image.nix {
-      name = "nixos-ova-${config.system.nixosLabel}-${pkgs.stdenv.system}";
+      name = "nixos-ova-${config.system.nixos.label}-${pkgs.stdenv.system}";
 
       inherit pkgs lib config;
       partitionTableType = "legacy";
@@ -37,7 +37,7 @@ in {
           VBoxManage internalcommands createrawvmdk -filename disk.vmdk -rawdisk $diskImage
 
           echo "creating VirtualBox VM..."
-          vmName="NixOS ${config.system.nixosLabel} (${pkgs.stdenv.system})"
+          vmName="NixOS ${config.system.nixos.label} (${pkgs.stdenv.system})"
           VBoxManage createvm --name "$vmName" --register \
             --ostype ${if pkgs.stdenv.system == "x86_64-linux" then "Linux26_64" else "Linux26"}
           VBoxManage modifyvm "$vmName" \
@@ -53,7 +53,7 @@ in {
 
           echo "exporting VirtualBox VM..."
           mkdir -p $out
-          fn="$out/nixos-${config.system.nixosLabel}-${pkgs.stdenv.system}.ova"
+          fn="$out/nixos-${config.system.nixos.label}-${pkgs.stdenv.system}.ova"
           VBoxManage export "$vmName" --output "$fn"
 
           rm -v $diskImage
diff --git a/nixos/release.nix b/nixos/release.nix
index 6bf2e4d8c7f8..8095dfeab843 100644
--- a/nixos/release.nix
+++ b/nixos/release.nix
@@ -35,8 +35,8 @@ let
 
 
   versionModule =
-    { system.nixosVersionSuffix = versionSuffix;
-      system.nixosRevision = nixpkgs.rev or nixpkgs.shortRev;
+    { system.nixos.versionSuffix = versionSuffix;
+      system.nixos.revision = nixpkgs.rev or nixpkgs.shortRev;
     };
 
 
diff --git a/nixos/tests/bittorrent.nix b/nixos/tests/bittorrent.nix
index 3a718a798315..50c98664660a 100644
--- a/nixos/tests/bittorrent.nix
+++ b/nixos/tests/bittorrent.nix
@@ -16,7 +16,7 @@ let
   miniupnpdConf = nodes: pkgs.writeText "miniupnpd.conf"
     ''
       ext_ifname=eth1
-      listening_ip=${(pkgs.lib.head nodes.router.config.networking.interfaces.eth2.ip4).address}/24
+      listening_ip=${(pkgs.lib.head nodes.router.config.networking.interfaces.eth2.ipv4.addresses).address}/24
       allow 1024-65535 192.168.2.0/24 1024-65535
     '';
 
@@ -56,7 +56,7 @@ in
         { environment.systemPackages = [ pkgs.transmission ];
           virtualisation.vlans = [ 2 ];
           networking.defaultGateway =
-            (pkgs.lib.head nodes.router.config.networking.interfaces.eth2.ip4).address;
+            (pkgs.lib.head nodes.router.config.networking.interfaces.eth2.ipv4.addresses).address;
           networking.firewall.enable = false;
         };
 
@@ -84,7 +84,7 @@ in
       # Create the torrent.
       $tracker->succeed("mkdir /tmp/data");
       $tracker->succeed("cp ${file} /tmp/data/test.tar.bz2");
-      $tracker->succeed("transmission-create /tmp/data/test.tar.bz2 -p -t http://${(pkgs.lib.head nodes.tracker.config.networking.interfaces.eth1.ip4).address}:6969/announce -o /tmp/test.torrent");
+      $tracker->succeed("transmission-create /tmp/data/test.tar.bz2 -p -t http://${(pkgs.lib.head nodes.tracker.config.networking.interfaces.eth1.ipv4.addresses).address}:6969/announce -o /tmp/test.torrent");
       $tracker->succeed("chmod 644 /tmp/test.torrent");
 
       # Start the tracker.  !!! use a less crappy tracker
diff --git a/nixos/tests/cjdns.nix b/nixos/tests/cjdns.nix
index 466663799241..4d3b58abc6e5 100644
--- a/nixos/tests/cjdns.nix
+++ b/nixos/tests/cjdns.nix
@@ -12,7 +12,6 @@ let
       # the sequence of address assignment less stochastic.
       networking.useDHCP = false;
 
-      networking.interfaces.eth1.prefixLength = 24;
       # CJDNS output is incompatible with the XML log.
       systemd.services.cjdns.serviceConfig.StandardOutput = "null";
       #networking.firewall.enable = true;
@@ -49,7 +48,9 @@ import ./make-test.nix ({ pkgs, ...} : {
 
           { imports = [ basicConfig ];
 
-          networking.interfaces.eth1.ipAddress = "192.168.0.2";
+          networking.interfaces.eth1.ipv4.addresses = [
+            { address = "192.168.0.2"; prefixLength = 24; }
+          ];
 
           services.cjdns =
             { UDPInterface =
@@ -76,7 +77,9 @@ import ./make-test.nix ({ pkgs, ...} : {
             CJDNS_ADMIN_PASSWORD=FOOBAR
           '';
 
-          networking.interfaces.eth1.ipAddress = "192.168.0.1";
+          networking.interfaces.eth1.ipv4.addresses = [
+            { address = "192.168.0.1"; prefixLength = 24; }
+          ];
 
           services.cjdns =
             { authorizedPasswords = [ carolPassword ];
diff --git a/nixos/tests/containers-bridge.nix b/nixos/tests/containers-bridge.nix
index b8d4759684cc..dfef46a2ada4 100644
--- a/nixos/tests/containers-bridge.nix
+++ b/nixos/tests/containers-bridge.nix
@@ -26,8 +26,8 @@ import ./make-test.nix ({ pkgs, ...} : {
       };
       networking.interfaces = {
         br0 = {
-          ip4 = [{ address = hostIp; prefixLength = 24; }];
-          ip6 = [{ address = hostIp6; prefixLength = 7; }];
+          ipv4.addresses = [{ address = hostIp; prefixLength = 24; }];
+          ipv6.addresses = [{ address = hostIp6; prefixLength = 7; }];
         };
       };
 
diff --git a/nixos/tests/containers-extra_veth.nix b/nixos/tests/containers-extra_veth.nix
index 6339c8c558b9..df3f3354b2d9 100644
--- a/nixos/tests/containers-extra_veth.nix
+++ b/nixos/tests/containers-extra_veth.nix
@@ -21,11 +21,11 @@ import ./make-test.nix ({ pkgs, ...} : {
       };
       networking.interfaces = {
         br0 = {
-          ip4 = [{ address = "192.168.0.1"; prefixLength = 24; }];
-          ip6 = [{ address = "fc00::1"; prefixLength = 7; }];
+          ipv4.addresses = [{ address = "192.168.0.1"; prefixLength = 24; }];
+          ipv6.addresses = [{ address = "fc00::1"; prefixLength = 7; }];
         };
         br1 = {
-          ip4 = [{ address = "192.168.1.1"; prefixLength = 24; }];
+          ipv4.addresses = [{ address = "192.168.1.1"; prefixLength = 24; }];
         };
       };
 
diff --git a/nixos/tests/containers-hosts.nix b/nixos/tests/containers-hosts.nix
index c7a85f190a5d..df1ef6d14936 100644
--- a/nixos/tests/containers-hosts.nix
+++ b/nixos/tests/containers-hosts.nix
@@ -13,9 +13,9 @@ import ./make-test.nix ({ pkgs, ...} : {
       virtualisation.vlans = [];
 
       networking.bridges.br0.interfaces = [];
-      networking.interfaces.br0 = {
-        ip4 = [ { address = "10.11.0.254"; prefixLength = 24; } ];
-      };
+      networking.interfaces.br0.ipv4.addresses = [
+        { address = "10.11.0.254"; prefixLength = 24; }
+      ];
 
       # Force /etc/hosts to be the only source for host name resolution
       environment.etc."nsswitch.conf".text = lib.mkForce ''
diff --git a/nixos/tests/containers-macvlans.nix b/nixos/tests/containers-macvlans.nix
index 721f98481497..390dc4ad2c29 100644
--- a/nixos/tests/containers-macvlans.nix
+++ b/nixos/tests/containers-macvlans.nix
@@ -26,9 +26,9 @@ import ./make-test.nix ({ pkgs, ...} : {
           interface = "eth1";
           mode = "bridge";
         };
-        networking.interfaces.eth1.ip4 = lib.mkForce [];
+        networking.interfaces.eth1.ipv4.addresses = lib.mkForce [];
         networking.interfaces.mv-eth1-host = {
-          ip4 = [ { address = "192.168.1.1"; prefixLength = 24; } ];
+          ipv4.addresses = [ { address = "192.168.1.1"; prefixLength = 24; } ];
         };
 
         containers.test1 = {
@@ -37,7 +37,7 @@ import ./make-test.nix ({ pkgs, ...} : {
 
           config = {
             networking.interfaces.mv-eth1 = {
-              ip4 = [ { address = containerIp1; prefixLength = 24; } ];
+              ipv4.addresses = [ { address = containerIp1; prefixLength = 24; } ];
             };
           };
         };
@@ -48,7 +48,7 @@ import ./make-test.nix ({ pkgs, ...} : {
 
           config = {
             networking.interfaces.mv-eth1 = {
-              ip4 = [ { address = containerIp2; prefixLength = 24; } ];
+              ipv4.addresses = [ { address = containerIp2; prefixLength = 24; } ];
             };
           };
         };
diff --git a/nixos/tests/containers-physical_interfaces.nix b/nixos/tests/containers-physical_interfaces.nix
index a3b0b29951bf..bd1228b8e37d 100644
--- a/nixos/tests/containers-physical_interfaces.nix
+++ b/nixos/tests/containers-physical_interfaces.nix
@@ -16,9 +16,9 @@ import ./make-test.nix ({ pkgs, ...} : {
           interfaces = [ "eth1" ];
 
           config = {
-            networking.interfaces.eth1 = {
-              ip4 = [ { address = "10.10.0.1"; prefixLength = 24; } ];
-            };
+            networking.interfaces.eth1.ipv4.addresses = [
+              { address = "10.10.0.1"; prefixLength = 24; }
+            ];
             networking.firewall.enable = false;
           };
         };
@@ -33,9 +33,9 @@ import ./make-test.nix ({ pkgs, ...} : {
 
         config = {
           networking.bridges.br0.interfaces = [ "eth1" ];
-          networking.interfaces.br0 = {
-            ip4 = [ { address = "10.10.0.2"; prefixLength = 24; } ];
-          };
+          networking.interfaces.br0.ipv4.addresses = [
+            { address = "10.10.0.2"; prefixLength = 24; }
+          ];
           networking.firewall.enable = false;
         };
       };
@@ -54,9 +54,9 @@ import ./make-test.nix ({ pkgs, ...} : {
             interfaces = [ "eth1" ];
             mode = "active-backup";
           };
-          networking.interfaces.bond0 = {
-            ip4 = [ { address = "10.10.0.3"; prefixLength = 24; } ];
-          };
+          networking.interfaces.bond0.ipv4.addresses = [
+            { address = "10.10.0.3"; prefixLength = 24; }
+          ];
           networking.firewall.enable = false;
         };
       };
@@ -76,9 +76,9 @@ import ./make-test.nix ({ pkgs, ...} : {
             mode = "active-backup";
           };
           networking.bridges.br0.interfaces = [ "bond0" ];
-          networking.interfaces.br0 = {
-            ip4 = [ { address = "10.10.0.4"; prefixLength = 24; } ];
-          };
+          networking.interfaces.br0.ipv4.addresses = [
+            { address = "10.10.0.4"; prefixLength = 24; }
+          ];
           networking.firewall.enable = false;
         };
       };
diff --git a/nixos/tests/containers-reloadable.nix b/nixos/tests/containers-reloadable.nix
index b5867c6f6ab1..5fb42f2272b3 100644
--- a/nixos/tests/containers-reloadable.nix
+++ b/nixos/tests/containers-reloadable.nix
@@ -11,7 +11,7 @@ let
 
     # prevent make-test.nix to change IP
     networking.interfaces = {
-      eth1.ip4 = lib.mkOverride 0 [ ];
+      eth1.ipv4.addresses = lib.mkOverride 0 [ ];
     };
   };
 in {
diff --git a/nixos/tests/containers-restart_networking.nix b/nixos/tests/containers-restart_networking.nix
index 086d056c51cd..f68c9b07759b 100644
--- a/nixos/tests/containers-restart_networking.nix
+++ b/nixos/tests/containers-restart_networking.nix
@@ -11,7 +11,7 @@ let
       config = {
         networking.firewall.enable = false;
         networking.firewall.allowPing = true;
-        networking.interfaces.eth0.ip4 = [
+        networking.interfaces.eth0.ipv4.addresses = [
           { address = "192.168.1.122"; prefixLength = 24; }
         ];
       };
@@ -33,8 +33,8 @@ in import ./make-test.nix ({ pkgs, lib, ...} :
         rstp = false;
       };
       networking.interfaces = {
-        eth1.ip4 = lib.mkOverride 0 [ ];
-        br0.ip4 = [{ address = "192.168.1.1"; prefixLength = 24; }];
+        eth1.ipv4.addresses = lib.mkOverride 0 [ ];
+        br0.ipv4.addresses = [ { address = "192.168.1.1"; prefixLength = 24; } ];
       };
 
     };
@@ -44,8 +44,8 @@ in import ./make-test.nix ({ pkgs, lib, ...} :
         rstp = false;
       };
       networking.interfaces = {
-        eth1.ip4 = lib.mkOverride 0 [ ];
-        br0.ip4 = [{ address = "192.168.1.2"; prefixLength = 24; }];
+        eth1.ipv4.addresses = lib.mkOverride 0 [ ];
+        br0.ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ];
       };
     };
     client_eth1_rstp = { lib, pkgs, ... }: client_base // {
@@ -54,8 +54,8 @@ in import ./make-test.nix ({ pkgs, lib, ...} :
         rstp = true;
       };
       networking.interfaces = {
-        eth1.ip4 = lib.mkOverride 0 [ ];
-        br0.ip4 = [{ address = "192.168.1.2"; prefixLength = 24; }];
+        eth1.ipv4.addresses = lib.mkOverride 0 [ ];
+        br0.ipv4.addresses =  [ { address = "192.168.1.2"; prefixLength = 24; } ];
       };
     };
   };
diff --git a/nixos/tests/ferm.nix b/nixos/tests/ferm.nix
index 8f2a8c01eebc..bb7daae118c0 100644
--- a/nixos/tests/ferm.nix
+++ b/nixos/tests/ferm.nix
@@ -11,8 +11,8 @@ import ./make-test.nix ({ pkgs, ...} : {
         with pkgs.lib;
         {
           networking = {
-            interfaces.eth1.ip6 = mkOverride 0 [ { address = "fd00::2"; prefixLength = 64; } ];
-            interfaces.eth1.ip4 = mkOverride 0 [ { address = "192.168.1.2"; prefixLength = 24; } ];
+            interfaces.eth1.ipv6.addresses = mkOverride 0 [ { address = "fd00::2"; prefixLength = 64; } ];
+            interfaces.eth1.ipv4.addresses = mkOverride 0 [ { address = "192.168.1.2"; prefixLength = 24; } ];
           };
       };
       server =
@@ -20,8 +20,8 @@ import ./make-test.nix ({ pkgs, ...} : {
         with pkgs.lib;
         {
           networking = {
-            interfaces.eth1.ip6 = mkOverride 0 [ { address = "fd00::1"; prefixLength = 64; } ];
-            interfaces.eth1.ip4 = mkOverride 0 [ { address = "192.168.1.1"; prefixLength = 24; } ];
+            interfaces.eth1.ipv6.addresses = mkOverride 0 [ { address = "fd00::1"; prefixLength = 64; } ];
+            interfaces.eth1.ipv4.addresses = mkOverride 0 [ { address = "192.168.1.1"; prefixLength = 24; } ];
           };
 
           services = {
diff --git a/nixos/tests/initrd-network-ssh/default.nix b/nixos/tests/initrd-network-ssh/default.nix
index 9d476cb1a967..b1f3d147e862 100644
--- a/nixos/tests/initrd-network-ssh/default.nix
+++ b/nixos/tests/initrd-network-ssh/default.nix
@@ -11,9 +11,7 @@ import ../make-test.nix ({ pkgs, lib, ... }:
       { config, pkgs, ... }:
       {
         boot.kernelParams = [
-          "ip=${
-            (head config.networking.interfaces.eth1.ip4).address
-          }:::255.255.255.0::eth1:none"
+          "ip=${config.networking.primaryIPAddress}:::255.255.255.0::eth1:none"
         ];
         boot.initrd.network = {
           enable = true;
diff --git a/nixos/tests/ipv6.nix b/nixos/tests/ipv6.nix
index 060f63216796..7a98fd85cfda 100644
--- a/nixos/tests/ipv6.nix
+++ b/nixos/tests/ipv6.nix
@@ -47,7 +47,7 @@ import ./make-test.nix ({ pkgs, ...} : {
       # Detection).
       sub waitForAddress {
           my ($machine, $iface, $scope) = @_;
-          $machine->waitUntilSucceeds("[ `ip -o -6 addr show dev $iface scope $scope | grep -v tentative | wc -l` -eq 1 ]");
+          $machine->waitUntilSucceeds("[ `ip -o -6 addr show dev $iface scope $scope | grep -v tentative | wc -l` -ge 1 ]");
           my $ip = (split /[ \/]+/, $machine->succeed("ip -o -6 addr show dev $iface scope $scope"))[3];
           $machine->log("$scope address on $iface is $ip");
           return $ip;
diff --git a/nixos/tests/nat.nix b/nixos/tests/nat.nix
index a12b7645bc28..7057158a829b 100644
--- a/nixos/tests/nat.nix
+++ b/nixos/tests/nat.nix
@@ -35,7 +35,7 @@ import ./make-test.nix ({ pkgs, lib, withFirewall, withConntrackHelpers ? false,
             { virtualisation.vlans = [ 1 ];
               networking.firewall.allowPing = true;
               networking.defaultGateway =
-                (pkgs.lib.head nodes.router.config.networking.interfaces.eth2.ip4).address;
+                (pkgs.lib.head nodes.router.config.networking.interfaces.eth2.ipv4.addresses).address;
             }
             (lib.optionalAttrs withConntrackHelpers {
               networking.firewall.connectionTrackingModules = [ "ftp" ];
diff --git a/nixos/tests/networking.nix b/nixos/tests/networking.nix
index bcdbad3bab0c..5cb40af5799e 100644
--- a/nixos/tests/networking.nix
+++ b/nixos/tests/networking.nix
@@ -21,10 +21,8 @@ let
         firewall.allowedUDPPorts = [ 547 ];
         interfaces = mkOverride 0 (listToAttrs (flip map vlanIfs (n:
           nameValuePair "eth${toString n}" {
-            ipAddress = "192.168.${toString n}.1";
-            prefixLength = 24;
-            ipv6Address = "fd00:1234:5678:${toString n}::1";
-            ipv6PrefixLength = 64;
+            ipv4.addresses = [ { address = "192.168.${toString n}.1"; prefixLength = 24; } ];
+            ipv6.addresses = [ { address = "fd00:1234:5678:${toString n}::1"; prefixLength = 64; } ];
           })));
       };
       services.dhcpd4 = {
@@ -90,12 +88,12 @@ let
           firewall.allowPing = true;
           useDHCP = false;
           defaultGateway = "192.168.1.1";
-          interfaces.eth1.ip4 = mkOverride 0 [
+          interfaces.eth1.ipv4.addresses = mkOverride 0 [
             { address = "192.168.1.2"; prefixLength = 24; }
             { address = "192.168.1.3"; prefixLength = 32; }
             { address = "192.168.1.10"; prefixLength = 32; }
           ];
-          interfaces.eth2.ip4 = mkOverride 0 [
+          interfaces.eth2.ipv4.addresses = mkOverride 0 [
             { address = "192.168.2.2"; prefixLength = 24; }
           ];
         };
@@ -143,12 +141,12 @@ let
           firewall.allowPing = true;
           useDHCP = true;
           interfaces.eth1 = {
-            ip4 = mkOverride 0 [ ];
-            ip6 = mkOverride 0 [ ];
+            ipv4.addresses = mkOverride 0 [ ];
+            ipv6.addresses = mkOverride 0 [ ];
           };
           interfaces.eth2 = {
-            ip4 = mkOverride 0 [ ];
-            ip6 = mkOverride 0 [ ];
+            ipv4.addresses = mkOverride 0 [ ];
+            ipv6.addresses = mkOverride 0 [ ];
           };
         };
       };
@@ -198,10 +196,10 @@ let
           firewall.allowPing = true;
           useDHCP = false;
           interfaces.eth1 = {
-            ip4 = mkOverride 0 [ ];
+            ipv4.addresses = mkOverride 0 [ ];
             useDHCP = true;
           };
-          interfaces.eth2.ip4 = mkOverride 0 [ ];
+          interfaces.eth2.ipv4.addresses = mkOverride 0 [ ];
         };
       };
       testScript = { nodes, ... }:
@@ -241,9 +239,9 @@ let
             interfaces = [ "eth1" "eth2" ];
             driverOptions.mode = "balance-rr";
           };
-          interfaces.eth1.ip4 = mkOverride 0 [ ];
-          interfaces.eth2.ip4 = mkOverride 0 [ ];
-          interfaces.bond.ip4 = mkOverride 0
+          interfaces.eth1.ipv4.addresses = mkOverride 0 [ ];
+          interfaces.eth2.ipv4.addresses = mkOverride 0 [ ];
+          interfaces.bond.ipv4.addresses = mkOverride 0
             [ { inherit address; prefixLength = 30; } ];
         };
       };
@@ -274,7 +272,7 @@ let
           useNetworkd = networkd;
           firewall.allowPing = true;
           useDHCP = false;
-          interfaces.eth1.ip4 = mkOverride 0
+          interfaces.eth1.ipv4.addresses = mkOverride 0
             [ { inherit address; prefixLength = 24; } ];
         };
       };
@@ -289,9 +287,9 @@ let
           firewall.allowPing = true;
           useDHCP = false;
           bridges.bridge.interfaces = [ "eth1" "eth2" ];
-          interfaces.eth1.ip4 = mkOverride 0 [ ];
-          interfaces.eth2.ip4 = mkOverride 0 [ ];
-          interfaces.bridge.ip4 = mkOverride 0
+          interfaces.eth1.ipv4.addresses = mkOverride 0 [ ];
+          interfaces.eth2.ipv4.addresses = mkOverride 0 [ ];
+          interfaces.bridge.ipv4.addresses = mkOverride 0
             [ { address = "192.168.1.1"; prefixLength = 24; } ];
         };
       };
@@ -328,7 +326,7 @@ let
           firewall.allowPing = true;
           useDHCP = true;
           macvlans.macvlan.interface = "eth1";
-          interfaces.eth1.ip4 = mkOverride 0 [ ];
+          interfaces.eth1.ipv4.addresses = mkOverride 0 [ ];
         };
       };
       testScript = { nodes, ... }:
@@ -369,9 +367,9 @@ let
             local = address4;
             dev = "eth1";
           };
-          interfaces.eth1.ip4 = mkOverride 0
+          interfaces.eth1.ipv4.addresses = mkOverride 0
             [ { address = address4; prefixLength = 24; } ];
-          interfaces.sit.ip6 = mkOverride 0
+          interfaces.sit.ipv6.addresses = mkOverride 0
             [ { address = address6; prefixLength = 64; } ];
         };
       };
@@ -410,9 +408,9 @@ let
             id = 1;
             interface = "eth0";
           };
-          interfaces.eth0.ip4 = mkOverride 0 [ ];
-          interfaces.eth1.ip4 = mkOverride 0 [ ];
-          interfaces.vlan.ip4 = mkOverride 0
+          interfaces.eth0.ipv4.addresses = mkOverride 0 [ ];
+          interfaces.eth1.ipv4.addresses = mkOverride 0 [ ];
+          interfaces.vlan.ipv4.addresses = mkOverride 0
             [ { inherit address; prefixLength = 24; } ];
         };
       };
@@ -437,13 +435,13 @@ let
       name = "Virtual";
       machine = {
         networking.interfaces."tap0" = {
-          ip4 = [ { address = "192.168.1.1"; prefixLength = 24; } ];
-          ip6 = [ { address = "2001:1470:fffd:2096::"; prefixLength = 64; } ];
+          ipv4.addresses = [ { address = "192.168.1.1"; prefixLength = 24; } ];
+          ipv6.addresses = [ { address = "2001:1470:fffd:2096::"; prefixLength = 64; } ];
           virtual = true;
         };
         networking.interfaces."tun0" = {
-          ip4 = [ { address = "192.168.1.2"; prefixLength = 24; } ];
-          ip6 = [ { address = "2001:1470:fffd:2097::"; prefixLength = 64; } ];
+          ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ];
+          ipv6.addresses = [ { address = "2001:1470:fffd:2097::"; prefixLength = 64; } ];
           virtual = true;
         };
       };
@@ -483,9 +481,9 @@ let
         boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = true;
         networking = {
           useNetworkd = networkd;
-          interfaces.eth1 = {
-            ipv6Address = "fd00:1234:5678:1::1";
-            ipv6PrefixLength = 64;
+          interfaces.eth1.ipv6.addresses = singleton {
+            address = "fd00:1234:5678:1::1";
+            prefixLength = 64;
           };
         };
         services.radvd = {
@@ -511,8 +509,8 @@ let
           useDHCP = true;
           interfaces.eth1 = {
             preferTempAddress = true;
-            ip4 = mkOverride 0 [ ];
-            ip6 = mkOverride 0 [ ];
+            ipv4.addresses = mkOverride 0 [ ];
+            ipv6.addresses = mkOverride 0 [ ];
           };
         };
       };
@@ -533,6 +531,69 @@ let
           $client->waitUntilSucceeds("! ip route get fd00:1234:5678:1::1 | grep -q ':[a-f0-9]*ff:fe[a-f0-9]*:'");
         '';
     };
+    routes = {
+      name = "routes";
+      machine = {
+        networking.useDHCP = false;
+        networking.interfaces."eth0" = {
+          ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ];
+          ipv6.addresses = [ { address = "2001:1470:fffd:2097::"; prefixLength = 64; } ];
+          ipv6.routes = [
+            { address = "fdfd:b3f0::"; prefixLength = 48; }
+            { address = "2001:1470:fffd:2098::"; prefixLength = 64; via = "fdfd:b3f0::1"; }
+          ];
+          ipv4.routes = [
+            { address = "10.0.0.0"; prefixLength = 16; options = { mtu = "1500"; }; }
+            { address = "192.168.2.0"; prefixLength = 24; via = "192.168.1.1"; }
+          ];
+        };
+        virtualisation.vlans = [ ];
+      };
+
+      testScript = ''
+        my $targetIPv4Table = <<'END';
+        10.0.0.0/16 scope link mtu 1500 
+        192.168.1.0/24 proto kernel scope link src 192.168.1.2 
+        192.168.2.0/24 via 192.168.1.1 
+        END
+
+        my $targetIPv6Table = <<'END';
+        2001:1470:fffd:2097::/64 proto kernel metric 256 pref medium
+        2001:1470:fffd:2098::/64 via fdfd:b3f0::1 metric 1024 pref medium
+        fdfd:b3f0::/48 metric 1024 pref medium
+        END
+
+        $machine->start;
+        $machine->waitForUnit("network.target");
+
+        # test routing tables
+        my $ipv4Table = $machine->succeed("ip -4 route list dev eth0 | head -n3");
+        my $ipv6Table = $machine->succeed("ip -6 route list dev eth0 | head -n3");
+        "$ipv4Table" eq "$targetIPv4Table" or die(
+          "The IPv4 routing table does not match the expected one:\n",
+          "Result:\n", "$ipv4Table\n",
+          "Expected:\n", "$targetIPv4Table\n"
+        );
+        "$ipv6Table" eq "$targetIPv6Table" or die(
+          "The IPv6 routing table does not match the expected one:\n",
+          "Result:\n", "$ipv6Table\n",
+          "Expected:\n", "$targetIPv6Table\n"
+        );
+
+        # test clean-up of the tables
+        $machine->succeed("systemctl stop network-addresses-eth0");
+        my $ipv4Residue = $machine->succeed("ip -4 route list dev eth0 | head -n-3");
+        my $ipv6Residue = $machine->succeed("ip -6 route list dev eth0 | head -n-3");
+        $ipv4Residue eq "" or die(
+          "The IPv4 routing table has not been properly cleaned:\n",
+          "$ipv4Residue\n"
+        );
+        $ipv6Residue eq "" or die(
+          "The IPv6 routing table has not been properly cleaned:\n",
+          "$ipv6Residue\n"
+        );
+      '';
+    };
   };
 
 in mapAttrs (const (attrs: makeTest (attrs // {
diff --git a/nixos/tests/nsd.nix b/nixos/tests/nsd.nix
index 0b1082056f6f..ad4d4f822435 100644
--- a/nixos/tests/nsd.nix
+++ b/nixos/tests/nsd.nix
@@ -15,25 +15,31 @@ in import ./make-test.nix ({ pkgs, ...} : {
     clientv4 = { lib, nodes, ... }: {
       imports = [ common ];
       networking.nameservers = lib.mkForce [
-        nodes.server.config.networking.interfaces.eth1.ipAddress
+        (lib.head nodes.server.config.networking.interfaces.eth1.ipv4.addresses).address
+      ];
+      networking.interfaces.eth1.ipv4.addresses = [
+        { address = "192.168.0.2"; prefixLength = 24; }
       ];
-      networking.interfaces.eth1.ipAddress = "192.168.0.2";
-      networking.interfaces.eth1.prefixLength = 24;
     };
 
     clientv6 = { lib, nodes, ... }: {
       imports = [ common ];
       networking.nameservers = lib.mkForce [
-        nodes.server.config.networking.interfaces.eth1.ipv6Address
+        (lib.head nodes.server.config.networking.interfaces.eth1.ipv6.addresses).address
+      ];
+      networking.interfaces.eth1.ipv4.addresses = [
+        { address = "dead:beef::2"; prefixLength = 24; }
       ];
-      networking.interfaces.eth1.ipv6Address = "dead:beef::2";
     };
 
     server = { lib, ... }: {
       imports = [ common ];
-      networking.interfaces.eth1.ipAddress = "192.168.0.1";
-      networking.interfaces.eth1.prefixLength = 24;
-      networking.interfaces.eth1.ipv6Address = "dead:beef::1";
+      networking.interfaces.eth1.ipv4.addresses = [
+        { address = "192.168.0.1"; prefixLength = 24; }
+      ];
+      networking.interfaces.eth1.ipv6.addresses = [
+        { address = "dead:beef::1"; prefixLength = 64; }
+      ];
       services.nsd.enable = true;
       services.nsd.interfaces = lib.mkForce [];
       services.nsd.zones."example.com.".data = ''
diff --git a/nixos/tests/quagga.nix b/nixos/tests/quagga.nix
index b9644b4768c0..613180942c41 100644
--- a/nixos/tests/quagga.nix
+++ b/nixos/tests/quagga.nix
@@ -8,7 +8,7 @@
 import ./make-test.nix ({ pkgs, ... }:
   let
 
-    ifAddr = node: iface: (pkgs.lib.head node.config.networking.interfaces.${iface}.ip4).address;
+    ifAddr = node: iface: (pkgs.lib.head node.config.networking.interfaces.${iface}.ipv4.addresses).address;
 
     ospfConf = ''
       interface eth2
diff --git a/pkgs/applications/editors/leo-editor/default.nix b/pkgs/applications/editors/leo-editor/default.nix
index b05bbd053c1f..2084a047a086 100644
--- a/pkgs/applications/editors/leo-editor/default.nix
+++ b/pkgs/applications/editors/leo-editor/default.nix
@@ -1,20 +1,29 @@
-{ stdenv, python3Packages, fetchFromGitHub, makeWrapper, makeDesktopItem }:
+{ stdenv, python3, libsForQt56, fetchFromGitHub, makeWrapper, makeDesktopItem }:
 
+let
+  packageOverrides = self: super: {
+    pyqt56 = libsForQt56.callPackage ../../../development/python-modules/pyqt/5.x.nix {
+      pythonPackages = self;
+    };
+  };
+
+  pythonPackages = (python3.override { inherit packageOverrides; }).pkgs;
+in
 stdenv.mkDerivation rec {
   name = "leo-editor-${version}";
-  version = "5.5";
+  version = "5.6";
 
   src = fetchFromGitHub {
     owner = "leo-editor";
     repo = "leo-editor";
     rev = version;
-    sha256 = "0crzljirzfiy9xn02ydd23clmd8bzdjxkyxdqsvdkgfy9j41b8hr";
+    sha256 = "1k6q3gvaf05bi0mzkmmb1p6wrgxwri7ivn38p6f0m0wfd3f70x2j";
   };
 
   dontBuild = true;
 
-  nativeBuildInputs = [ makeWrapper python3Packages.python ];
-  propagatedBuildInputs = with python3Packages; [ pyqt5 ];
+  nativeBuildInputs = [ makeWrapper python3 ];
+  propagatedBuildInputs = with pythonPackages; [ pyqt56 docutils ];
 
   desktopItem = makeDesktopItem rec {
     name = "leo-editor";
@@ -50,7 +59,7 @@ stdenv.mkDerivation rec {
     mkdir -p $out/share/leo-editor
     mv * $out/share/leo-editor
 
-    makeWrapper ${python3Packages.python.interpreter} $out/bin/leo \
+    makeWrapper ${python3.interpreter} $out/bin/leo \
       --set PYTHONPATH "$PYTHONPATH:$out/share/leo-editor" \
       --add-flags "-O $out/share/leo-editor/launchLeo.py"
   '';
diff --git a/pkgs/applications/misc/jekyll/Gemfile.lock b/pkgs/applications/misc/jekyll/Gemfile.lock
index da4be83382fb..899850ae9954 100644
--- a/pkgs/applications/misc/jekyll/Gemfile.lock
+++ b/pkgs/applications/misc/jekyll/Gemfile.lock
@@ -2,47 +2,67 @@ GEM
   remote: https://rubygems.org/
   specs:
     RedCloth (4.3.2)
-    addressable (2.5.0)
-      public_suffix (~> 2.0, >= 2.0.2)
+    addressable (2.5.2)
+      public_suffix (>= 2.0.2, < 4.0)
     colorator (1.1.0)
-    ffi (1.9.18)
+    concurrent-ruby (1.0.5)
+    em-websocket (0.5.1)
+      eventmachine (>= 0.12.9)
+      http_parser.rb (~> 0.6.0)
+    eventmachine (1.2.5)
+    ffi (1.9.21)
     forwardable-extended (2.6.0)
-    jekyll (3.4.1)
+    http_parser.rb (0.6.0)
+    i18n (0.9.5)
+      concurrent-ruby (~> 1.0)
+    jekyll (3.7.2)
       addressable (~> 2.4)
       colorator (~> 1.0)
+      em-websocket (~> 0.5)
+      i18n (~> 0.7)
       jekyll-sass-converter (~> 1.0)
-      jekyll-watch (~> 1.1)
-      kramdown (~> 1.3)
-      liquid (~> 3.0)
+      jekyll-watch (~> 2.0)
+      kramdown (~> 1.14)
+      liquid (~> 4.0)
       mercenary (~> 0.3.3)
       pathutil (~> 0.9)
-      rouge (~> 1.7)
+      rouge (>= 1.7, < 4)
       safe_yaml (~> 1.0)
-    jekyll-feed (0.9.1)
+    jekyll-feed (0.9.3)
       jekyll (~> 3.3)
     jekyll-paginate (1.1.0)
-    jekyll-sass-converter (1.5.0)
+    jekyll-sass-converter (1.5.2)
       sass (~> 3.4)
-    jekyll-watch (1.5.0)
-      listen (~> 3.0, < 3.1)
-    kramdown (1.13.2)
-    liquid (3.0.6)
-    listen (3.0.8)
+    jekyll-seo-tag (2.4.0)
+      jekyll (~> 3.3)
+    jekyll-watch (2.0.0)
+      listen (~> 3.0)
+    kramdown (1.16.2)
+    liquid (4.0.0)
+    listen (3.1.5)
       rb-fsevent (~> 0.9, >= 0.9.4)
       rb-inotify (~> 0.9, >= 0.9.7)
+      ruby_dep (~> 1.2)
     mercenary (0.3.6)
-    minima (2.1.0)
-      jekyll (~> 3.3)
-    pathutil (0.14.0)
+    minima (2.3.0)
+      jekyll (~> 3.5)
+      jekyll-feed (~> 0.9)
+      jekyll-seo-tag (~> 2.1)
+    pathutil (0.16.1)
       forwardable-extended (~> 2.6)
-    public_suffix (2.0.5)
-    rb-fsevent (0.9.8)
-    rb-inotify (0.9.8)
-      ffi (>= 0.5.0)
+    public_suffix (3.0.2)
+    rb-fsevent (0.10.2)
+    rb-inotify (0.9.10)
+      ffi (>= 0.5.0, < 2)
     rdiscount (2.2.0.1)
-    rouge (1.11.1)
+    rouge (3.1.1)
+    ruby_dep (1.5.0)
     safe_yaml (1.0.4)
-    sass (3.4.23)
+    sass (3.5.5)
+      sass-listen (~> 4.0.0)
+    sass-listen (4.0.0)
+      rb-fsevent (~> 0.9, >= 0.9.4)
+      rb-inotify (~> 0.9, >= 0.9.7)
 
 PLATFORMS
   ruby
@@ -56,4 +76,4 @@ DEPENDENCIES
   rdiscount
 
 BUNDLED WITH
-   1.14.4
+   1.14.6
diff --git a/pkgs/applications/misc/jekyll/default.nix b/pkgs/applications/misc/jekyll/default.nix
index ad8b7b262e55..cb094d755f7c 100644
--- a/pkgs/applications/misc/jekyll/default.nix
+++ b/pkgs/applications/misc/jekyll/default.nix
@@ -1,19 +1,18 @@
 { stdenv, lib, bundlerEnv, ruby }:
 
 bundlerEnv rec {
-  name = "jekyll-${version}";
+  name = pname + "-" + version;
+  pname = "jekyll";
+  version = (import ./gemset.nix).jekyll.version;
 
-  version = (import gemset).jekyll.version;
   inherit ruby;
-  gemfile = ./Gemfile;
-  lockfile = ./Gemfile.lock;
-  gemset = ./gemset.nix;
+  gemdir = ./.;
 
   meta = with lib; {
     description = "Simple, blog aware, static site generator";
-    homepage    =  https://jekyllrb.com/;
+    homepage    = https://jekyllrb.com/;
     license     = licenses.mit;
-    maintainers = with maintainers; [ pesterhazy ];
+    maintainers = with maintainers; [ primeos pesterhazy ];
     platforms   = platforms.unix;
   };
 }
diff --git a/pkgs/applications/misc/jekyll/gemset.nix b/pkgs/applications/misc/jekyll/gemset.nix
index 5b1a35209aeb..c4a68c7becd2 100644
--- a/pkgs/applications/misc/jekyll/gemset.nix
+++ b/pkgs/applications/misc/jekyll/gemset.nix
@@ -1,11 +1,12 @@
 {
   addressable = {
+    dependencies = ["public_suffix"];
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "1j5r0anj8m4qlf2psnldip4b8ha2bsscv11lpdgnfh4nnchzjnxw";
+      sha256 = "0viqszpkggqi8hq87pqp0xykhvz60g99nwmkwsb0v45kc2liwxvk";
       type = "gem";
     };
-    version = "2.5.0";
+    version = "2.5.2";
   };
   colorator = {
     source = {
@@ -15,13 +16,38 @@
     };
     version = "1.1.0";
   };
+  concurrent-ruby = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "183lszf5gx84kcpb779v6a2y0mx9sssy8dgppng1z9a505nj1qcf";
+      type = "gem";
+    };
+    version = "1.0.5";
+  };
+  em-websocket = {
+    dependencies = ["eventmachine" "http_parser.rb"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1bsw8vjz0z267j40nhbmrvfz7dvacq4p0pagvyp17jif6mj6v7n3";
+      type = "gem";
+    };
+    version = "0.5.1";
+  };
+  eventmachine = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "075hdw0fgzldgss3xaqm2dk545736khcvv1fmzbf1sgdlkyh1v8z";
+      type = "gem";
+    };
+    version = "1.2.5";
+  };
   ffi = {
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "034f52xf7zcqgbvwbl20jwdyjwznvqnwpbaps9nk18v9lgb1dpx0";
+      sha256 = "0c2dl10pi6a30kcvx2s6p2v1wb4kbm48iv38kmz2ff600nirhpb8";
       type = "gem";
     };
-    version = "1.9.18";
+    version = "1.9.21";
   };
   forwardable-extended = {
     source = {
@@ -31,67 +57,100 @@
     };
     version = "2.6.0";
   };
+  "http_parser.rb" = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "15nidriy0v5yqfjsgsra51wmknxci2n2grliz78sf9pga3n0l7gi";
+      type = "gem";
+    };
+    version = "0.6.0";
+  };
+  i18n = {
+    dependencies = ["concurrent-ruby"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "038qvz7kd3cfxk8bvagqhakx68pfbnmghpdkx7573wbf0maqp9a3";
+      type = "gem";
+    };
+    version = "0.9.5";
+  };
   jekyll = {
+    dependencies = ["addressable" "colorator" "em-websocket" "i18n" "jekyll-sass-converter" "jekyll-watch" "kramdown" "liquid" "mercenary" "pathutil" "rouge" "safe_yaml"];
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "0qbnjx7bpshbcam6p9ss2g6gpd3gxz6h4w9yszphj3ip335yhawb";
+      sha256 = "05f61rqwz1isci7by34zyz38ah2rv5b8i5h618cxcl97hwqps8n2";
       type = "gem";
     };
-    version = "3.4.1";
+    version = "3.7.2";
   };
   jekyll-feed = {
+    dependencies = ["jekyll"];
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "1dj62gy1jskkn703mi5h0bkg1psbpkdm2qqdw3bhjfid9358qvay";
+      sha256 = "0kr3kyaq4z3jixn6ay8h16bxxlv6slvvp7nqnl05jdymhkl0bmm9";
       type = "gem";
     };
-    version = "0.9.1";
+    version = "0.9.3";
   };
   jekyll-paginate = {
     source = {
+      remotes = ["https://rubygems.org"];
       sha256 = "0r7bcs8fq98zldih4787zk5i9w24nz5wa26m84ssja95n3sas2l8";
       type = "gem";
     };
     version = "1.1.0";
   };
   jekyll-sass-converter = {
+    dependencies = ["sass"];
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "01m921763yfgx1gc33k5ixqz623f4c4azgnpqhgsc2q61fyfk3q1";
+      sha256 = "008ikh5fk0n6ri54mylcl8jn0mq8p2nfyfqif2q3pp0lwilkcxsk";
       type = "gem";
     };
-    version = "1.5.0";
+    version = "1.5.2";
+  };
+  jekyll-seo-tag = {
+    dependencies = ["jekyll"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "0f9b2mvmx57zj49afb3x8cmzdmb1kh4rbpbv3v7w5bh47g2c9big";
+      type = "gem";
+    };
+    version = "2.4.0";
   };
   jekyll-watch = {
+    dependencies = ["listen"];
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "02rg3wi95w2l0bg1igl5k6pza723vn2b2gj975gycz1cpmhdjn6z";
+      sha256 = "0m7scvj3ki8bmyx5v8pzibpg6my10nycnc28lip98dskf8iakprp";
       type = "gem";
     };
-    version = "1.5.0";
+    version = "2.0.0";
   };
   kramdown = {
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "1isiqc40q44zg57bd6cfnw1a2l0s2j5skw2awn2cz3gcm7wsf49d";
+      sha256 = "0mkrqpp01rrfn3rx6wwsjizyqmafp0vgg8ja1dvbjs185r5zw3za";
       type = "gem";
     };
-    version = "1.13.2";
+    version = "1.16.2";
   };
   liquid = {
     source = {
-      sha256 = "033png37ym4jrjz5bi7zb4ic4yxacwvnllm1xxmrnr4swgyyygc2";
+      remotes = ["https://rubygems.org"];
+      sha256 = "17fa0jgwm9a935fyvzy8bysz7j5n1vf1x2wzqkdfd5k08dbw3x2y";
       type = "gem";
     };
-    version = "3.0.6";
+    version = "4.0.0";
   };
   listen = {
+    dependencies = ["rb-fsevent" "rb-inotify" "ruby_dep"];
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "1l0y7hbyfiwpvk172r28hsdqsifq1ls39hsfmzi1vy4ll0smd14i";
+      sha256 = "01v5mrnfqm6sgm8xn2v5swxsn1wlmq7rzh2i48d4jzjsc7qvb6mx";
       type = "gem";
     };
-    version = "3.0.8";
+    version = "3.1.5";
   };
   mercenary = {
     source = {
@@ -102,44 +161,47 @@
     version = "0.3.6";
   };
   minima = {
+    dependencies = ["jekyll" "jekyll-feed" "jekyll-seo-tag"];
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "1s7ks9fqfvqx7qicnkrg76wavg9mjas52f7iyhr89lz9mqiy7p39";
+      sha256 = "0pasyjszlj4ir1zlbrq8ggydgdaib5zbbs5vjbvyla66ip9jrdji";
       type = "gem";
     };
-    version = "2.1.0";
+    version = "2.3.0";
   };
   pathutil = {
+    dependencies = ["forwardable-extended"];
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "0f444wx6vjd30lkkb2zn1k5a6g33lidrpyy7lmgy66n1gsiipzn7";
+      sha256 = "0wc18ms1rzi44lpjychyw2a96jcmgxqdvy2949r4vvb5f4p0lgvz";
       type = "gem";
     };
-    version = "0.14.0";
+    version = "0.16.1";
   };
   public_suffix = {
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "040jf98jpp6w140ghkhw2hvc1qx41zvywx5gj7r2ylr1148qnj7q";
+      sha256 = "1x5h1dh1i3gwc01jbg01rly2g6a1qwhynb1s8a30ic507z1nh09s";
       type = "gem";
     };
-    version = "2.0.5";
+    version = "3.0.2";
   };
   rb-fsevent = {
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "1pdiasp9zlr306yld19szapi6kdjk38rpv1hih9x0ry40x6mb63n";
+      sha256 = "1fbpmjypwxkb8r7y1kmhmyp6gawa4byw0yb3jc3dn9ly4ld9lizf";
       type = "gem";
     };
-    version = "0.9.8";
+    version = "0.10.2";
   };
   rb-inotify = {
+    dependencies = ["ffi"];
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "0bq14f3md5nm00kgxgf0r9lcbn0vgbwljgajif0slxcwv622fjg9";
+      sha256 = "0yfsgw5n7pkpyky6a9wkf1g9jafxb0ja7gz0qw0y14fd2jnzfh71";
       type = "gem";
     };
-    version = "0.9.8";
+    version = "0.9.10";
   };
   rdiscount = {
     source = {
@@ -160,24 +222,43 @@
   rouge = {
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "13amckbdknnc5491ag28y8pqbyfpbzx5n4rlmadxhd3wkrhp92c8";
+      sha256 = "1sfhy0xxqjnzqa7qxmpz1bmy0mzcr55qyvi410gsb6d6i4ialbw3";
       type = "gem";
     };
-    version = "1.11.1";
+    version = "3.1.1";
+  };
+  ruby_dep = {
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "1c1bkl97i9mkcvkn1jks346ksnvnnp84cs22gwl0vd7radybrgy5";
+      type = "gem";
+    };
+    version = "1.5.0";
   };
   safe_yaml = {
     source = {
+      remotes = ["https://rubygems.org"];
       sha256 = "1hly915584hyi9q9vgd968x2nsi5yag9jyf5kq60lwzi5scr7094";
       type = "gem";
     };
     version = "1.0.4";
   };
   sass = {
+    dependencies = ["sass-listen"];
+    source = {
+      remotes = ["https://rubygems.org"];
+      sha256 = "10401m2xlv6vaxfwzy4xxmk51ddcnkvwi918cw3jkki0qqdl7d8v";
+      type = "gem";
+    };
+    version = "3.5.5";
+  };
+  sass-listen = {
+    dependencies = ["rb-fsevent" "rb-inotify"];
     source = {
       remotes = ["https://rubygems.org"];
-      sha256 = "0da4mn3n60cm1ss1pw1rrpa7fxagglxiwcgvz1asf1qgf4mvcwyr";
+      sha256 = "0xw3q46cmahkgyldid5hwyiwacp590zj2vmswlll68ryvmvcp7df";
       type = "gem";
     };
-    version = "3.4.23";
+    version = "4.0.0";
   };
 }
\ No newline at end of file
diff --git a/pkgs/build-support/fetchurl/default.nix b/pkgs/build-support/fetchurl/default.nix
index 3e47d4a4b683..0bf529caa75e 100644
--- a/pkgs/build-support/fetchurl/default.nix
+++ b/pkgs/build-support/fetchurl/default.nix
@@ -1,4 +1,4 @@
-{ stdenvNoCC, curl }: # Note that `curl' may be `null', in case of the native stdenvNoCC.
+{ lib, stdenvNoCC, curl }: # Note that `curl' may be `null', in case of the native stdenvNoCC.
 
 let
 
@@ -20,7 +20,7 @@ let
   # "gnu", etc.).
   sites = builtins.attrNames mirrors;
 
-  impureEnvVars = stdenvNoCC.lib.fetchers.proxyImpureEnvVars ++ [
+  impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [
     # This variable allows the user to pass additional options to curl
     "NIX_CURL_FLAGS"
 
@@ -89,22 +89,28 @@ in
 , passthru ? {}
 }:
 
-assert builtins.isList urls;
-assert (urls == []) != (url == "");
 assert sha512 != "" -> builtins.compareVersions "1.11" builtins.nixVersion <= 0;
 
-
 let
 
-  hasHash = showURLs || (outputHash != "" && outputHashAlgo != "")
-    || sha1 != "" || sha256 != "" || sha512 != "";
-  urls_ = if urls != [] then urls else [url];
+  urls_ =
+    if urls != [] && url == "" then
+      (if lib.isList urls then urls
+       else throw "`urls` is not a list")
+    else if urls == [] && url != "" then [url]
+    else throw "fetchurl requires either `url` or `urls` to be set";
+
+  hash_ =
+    if md5 != "" then throw "fetchurl does not support md5 anymore, please use sha256 or sha512"
+    else if (outputHash != "" && outputHashAlgo != "") then { inherit outputHashAlgo outputHash; }
+    else if sha512 != "" then { outputHashAlgo = "sha512"; outputHash = sha512; }
+    else if sha256 != "" then { outputHashAlgo = "sha256"; outputHash = sha256; }
+    else if sha1   != "" then { outputHashAlgo = "sha1";   outputHash = sha1; }
+    else throw "fetchurl requires a hash for fixed-output derivation: ${lib.concatStringsSep ", " urls_}";
 
 in
 
-if md5 != "" then throw "fetchurl does not support md5 anymore, please use sha256 or sha512"
-else if (!hasHash) then throw "Specify hash for fetchurl fixed-output derivation: ${stdenvNoCC.lib.concatStringsSep ", " urls_}"
-else stdenvNoCC.mkDerivation {
+stdenvNoCC.mkDerivation {
   name =
     if showURLs then "urls"
     else if name != "" then name
@@ -121,10 +127,7 @@ else stdenvNoCC.mkDerivation {
   preferHashedMirrors = true;
 
   # New-style output content requirements.
-  outputHashAlgo = if outputHashAlgo != "" then outputHashAlgo else
-      if sha512 != "" then "sha512" else if sha256 != "" then "sha256" else "sha1";
-  outputHash = if outputHash != "" then outputHash else
-      if sha512 != "" then sha512 else if sha256 != "" then sha256 else sha1;
+  inherit (hash_) outputHashAlgo outputHash;
 
   outputHashMode = if (recursiveHash || executable) then "recursive" else "flat";
 
diff --git a/pkgs/development/interpreters/clojure/default.nix b/pkgs/development/interpreters/clojure/default.nix
index 6a652bde993c..7aac606fdfb2 100644
--- a/pkgs/development/interpreters/clojure/default.nix
+++ b/pkgs/development/interpreters/clojure/default.nix
@@ -2,11 +2,11 @@
 
 stdenv.mkDerivation rec {
   name = "clojure-${version}";
-  version = "1.9.0.273";
+  version = "1.9.0.329";
 
   src = fetchurl {
     url = "https://download.clojure.org/install/clojure-tools-${version}.tar.gz";
-    sha256 = "0xmrq3xvr002jgq8m1j0y5ld0rcr49608g3gqxgyxzjqswacglb4";
+    sha256 = "1g1mi75285z977vrqbihmmmrmdcnznxbw3r6wkzh571sc1yyrlrj";
   };
 
   buildInputs = [ makeWrapper ];
diff --git a/pkgs/development/libraries/aspell/dictionaries.nix b/pkgs/development/libraries/aspell/dictionaries.nix
index 8d97d6db2f1c..096ac80e5a70 100644
--- a/pkgs/development/libraries/aspell/dictionaries.nix
+++ b/pkgs/development/libraries/aspell/dictionaries.nix
@@ -1,32 +1,113 @@
-{stdenv, fetchurl, aspell, which}:
+{lib, stdenv, fetchurl, aspell, which}:
+
+with lib;
+
+/* HOWTO:
+
+   * Add some of these to your profile or systemPackages.
+
+     ~~~~
+     environment.systemPackages = [
+       aspell
+       aspellDicts.en
+       aspellDicts.en-computers
+       aspellDicts.en-science
+     ];
+     ~~~~
+
+   * Rebuild and switch to the new profile.
+   * Add something like
+
+     ~~~~
+     master en_US
+     extra-dicts en-computers.rws
+     add-extra-dicts en_US-science.rws
+     ~~~~
+
+     to `/etc/aspell.conf` or `~/.aspell.conf`.
+   * Check that `aspell -a` starts without errors.
+   * (optional) Check your config with `aspell dump config | grep -vE '^(#|$)'`.
+   * Enjoy.
+
+*/
 
 let
 
   /* Function to compile an Aspell dictionary.  Fortunately, they all
      build in the exact same way. */
   buildDict =
-    {shortName, fullName, src, postInstall ? ""}:
+    {shortName, fullName, ...}@args:
 
-    stdenv.mkDerivation {
+    stdenv.mkDerivation ({
       name = "aspell-dict-${shortName}";
 
-      inherit src;
-
       buildInputs = [aspell which];
 
       dontAddPrefix = true;
 
       preBuild = "makeFlagsArray=(dictdir=$out/lib/aspell datadir=$out/lib/aspell)";
 
-      inherit postInstall;
-
       meta = {
         description = "Aspell dictionary for ${fullName}";
         platforms = stdenv.lib.platforms.all;
-      };
-    };
-
-in {
+      } // (args.meta or {});
+    } // removeAttrs args [ "meta" ]);
+
+  /* Function to compile txt dict files into Aspell dictionaries. */
+  buildTxtDict =
+    {langInputs ? [], ...}@args:
+    buildDict ({
+      propagatedUserEnvPackages = langInputs;
+
+      preBuild = ''
+        # Aspell can't handle multiple data-dirs
+        # Copy everything we might possibly need
+        ${concatMapStringsSep "\n" (p: ''
+          cp -a ${p}/lib/aspell/* .
+        '') ([ aspell ] ++ langInputs)}
+        export ASPELL_CONF="data-dir $(pwd)"
+
+        aspell-create() {
+          target=$1
+          shift
+          echo building $target
+          aspell create "$@" master ./$target.rws
+        }
+
+        words-only() {
+          awk -F'\t' '{print $1}' | sort | uniq
+        }
+
+        # drop comments
+        aspell-affix() {
+          words-only \
+            | grep -v '#' \
+            | aspell-create "$@"
+        }
+
+        # Hack: drop comments and words with affixes
+        aspell-plain() {
+          words-only \
+            | grep -v '#' \
+            | grep -v '/' \
+            | aspell-create "$@"
+        }
+
+        aspell-install() {
+          install -d $out/lib/aspell
+          for a in "$@"; do
+            echo installing $a
+            install -t $out/lib/aspell $a.rws
+          done
+        }
+      '';
+
+      phases = [ "preBuild" "buildPhase" "installPhase" ];
+    } // args);
+
+in rec {
+
+  ### Languages
 
   ca = buildDict {
     shortName = "ca-2.1.5-1";
@@ -230,4 +311,53 @@ in {
     };
   };
 
+  ### Jargons
+
+  en-computers = buildTxtDict rec {
+    shortName = "en-computers";
+    fullName = "English Computer Jargon";
+
+    src = fetchurl {
+      url = https://mrsatterly.com/computer.dic;
+      sha256 = "1vzk7cdvcm9r1c6mgxpabrdcpvghdv9mjmnf6iq5wllcif5nsw2b";
+    };
+
+    langInputs = [ en ];
+
+    buildPhase = "cat $src | aspell-affix en-computers --dont-validate-words --lang=en";
+    installPhase = "aspell-install en-computers";
+
+    meta = {
+      homepage = https://mrsatterly.com/spelling.html;
+    };
+  };
+
+  en-science = buildTxtDict rec {
+    shortName = "en-science";
+    fullName = "English Scientific Jargon";
+
+    src1 = fetchurl {
+      url = http://jpetrie.net/wp-content/uploads/custom_scientific_US.txt;
+      sha256 = "1psqm094zl4prk2f8h18jv0d471hxykzd1zdnrlx7gzrzy6pz5r3";
+    };
+
+    src2 = fetchurl {
+      url = http://jpetrie.net/wp-content/uploads/custom_scientific_UK.txt;
+      sha256 = "17ss1sdr3k70zbyx2z9xf74345slrp41gbkpih8axrmg4x92fgm1";
+    };
+
+    langInputs = [ en ];
+
+    buildPhase = ''
+      cat $src1 | aspell-plain en_US-science --dont-validate-words --lang=en
+      cat $src2 | aspell-plain en_GB-science --dont-validate-words --lang=en
+    '';
+    installPhase = "aspell-install en_US-science en_GB-science";
+
+    meta = {
+      homepage = http://www.jpetrie.net/scientific-word-list-for-spell-checkersspelling-dictionaries/;
+    };
+
+  };
+
 }
diff --git a/pkgs/development/ocaml-modules/bitv/default.nix b/pkgs/development/ocaml-modules/bitv/default.nix
new file mode 100644
index 000000000000..359d83b4762a
--- /dev/null
+++ b/pkgs/development/ocaml-modules/bitv/default.nix
@@ -0,0 +1,27 @@
+{ stdenv, fetchzip, autoreconfHook, which, ocaml, findlib }:
+
+if !stdenv.lib.versionAtLeast ocaml.version "4.02"
+then throw "bitv is not available for OCaml ${ocaml.version}"
+else
+
+stdenv.mkDerivation rec {
+  name = "ocaml${ocaml.version}-bitv-${version}";
+  version = "1.3";
+
+  src = fetchzip {
+    url = "https://github.com/backtracking/bitv/archive/${version}.tar.gz";
+    sha256 = "0vkh1w9fpi5m1sgiqg6r38j3fqglhdajmbyiyr91113lrpljm75i";
+  };
+
+  buildInputs = [ autoreconfHook which ocaml findlib ];
+
+  createFindlibDestdir = true;
+
+  meta = {
+    description = "A bit vector library for OCaml";
+    license = stdenv.lib.licenses.lgpl21;
+    homepage = "https://github.com/backtracking/bitv";
+    maintainers = [ stdenv.lib.maintainers.vbgl ];
+    inherit (ocaml.meta) platforms;
+  };
+}
diff --git a/pkgs/development/tools/analysis/radare2/default.nix b/pkgs/development/tools/analysis/radare2/default.nix
index 49f6aeb72799..6a7992b01311 100644
--- a/pkgs/development/tools/analysis/radare2/default.nix
+++ b/pkgs/development/tools/analysis/radare2/default.nix
@@ -1,4 +1,4 @@
-{stdenv, fetchFromGitHub, fetchurl, fetchpatch, pkgconfig, libusb, readline, libewf, perl, zlib, openssl,
+{stdenv, fetchFromGitHub, fetchgit, fetchurl, fetchpatch, pkgconfig, libusb, readline, libewf, perl, zlib, openssl, git,
 gtk2 ? null, vte ? null, gtkdialog ? null,
 python ? null,
 ruby ? null,
@@ -13,32 +13,33 @@ let
   inherit (stdenv.lib) optional;
 in
 stdenv.mkDerivation rec {
-  version = "2.2.0";
+  version = "2.3.0";
   name = "radare2-${version}";
 
   src = fetchFromGitHub {
     owner = "radare";
     repo = "radare2";
     rev = version;
-    sha256 = "0rd1dfgwdpn3x1pzi67sw040vxywbg5h6yw0mj317p0p1cvlyihl";
+    sha256 = "0x5vcprqf0fnj876mdvryfvg7ymbrw1cxrr7a06v0swg7yql1lpw";
   };
 
   postPatch = let
-    cs_ver = "3.0.4"; # version from $sourceRoot/shlr/Makefile
-    capstone = fetchurl {
-      url = "https://github.com/aquynh/capstone/archive/${cs_ver}.tar.gz";
-      sha256 = "1whl5c8j6vqvz2j6ay2pyszx0jg8d3x8hq66cvgghmjchvsssvax";
+    cs_tip = "bdbc57de63725a98732ddc34b48de96f8ada66f2"; # version from $sourceRoot/shlr/Makefile
+    capstone = fetchgit {
+      url = "https://github.com/aquynh/capstone.git";
+      rev = cs_tip;
+      sha256 = "1sqxpjf2dlrg87dm9p39p5d1qzahrnfnrjijpv1xg1shax439jni";
+      leaveDotGit = true;
     };
   in ''
-    if ! grep -F "CS_VER=${cs_ver}" shlr/Makefile; then echo "CS_VER mismatch"; exit 1; fi
-    substituteInPlace shlr/Makefile --replace CS_RELEASE=0 CS_RELEASE=1
-    cp ${capstone} shlr/capstone-${cs_ver}.tar.gz
-
+    if ! grep -F "CS_TIP=${cs_tip}" shlr/Makefile; then echo "CS_TIP mismatch"; exit 1; fi
+    cp -r ${capstone} shlr/capstone
+    chmod -R u+rw shlr/capstone
   '';
 
   enableParallelBuilding = true;
 
-  nativeBuildInputs = [ pkgconfig ];
+  nativeBuildInputs = [ pkgconfig git ];
   buildInputs = [ readline libusb libewf perl zlib openssl]
     ++ optional useX11 [gtkdialog vte gtk2]
     ++ optional rubyBindings [ruby]
diff --git a/pkgs/development/tools/build-managers/gnumake/4.2/default.nix b/pkgs/development/tools/build-managers/gnumake/4.2/default.nix
index 1094cacb7af3..e175205143fc 100644
--- a/pkgs/development/tools/build-managers/gnumake/4.2/default.nix
+++ b/pkgs/development/tools/build-managers/gnumake/4.2/default.nix
@@ -4,8 +4,6 @@ assert guileSupport -> ( pkgconfig != null && guile != null );
 
 let
   version = "4.2.1";
-
-  needGlibcPatch = (stdenv.cc.libc.version or "") == "2.27";
 in
 stdenv.mkDerivation {
   name = "gnumake-${version}";
@@ -22,7 +20,7 @@ stdenv.mkDerivation {
     # included Makefiles, don't look in /usr/include and friends.
     ./impure-dirs.patch
     ./pselect.patch
-  ] ++ stdenv.lib.optional needGlibcPatch ./glibc-2.27.patch;
+  ];
 
   nativeBuildInputs = stdenv.lib.optionals guileSupport [ pkgconfig ];
   buildInputs = stdenv.lib.optionals guileSupport [ guile ];
diff --git a/pkgs/development/tools/build-managers/gnumake/4.2/head.nix b/pkgs/development/tools/build-managers/gnumake/4.2/head.nix
new file mode 100644
index 000000000000..5f3ae10c3e5b
--- /dev/null
+++ b/pkgs/development/tools/build-managers/gnumake/4.2/head.nix
@@ -0,0 +1,69 @@
+{ stdenv, fetchurl, texinfo, guileSupport ? false, pkgconfig , guile ? null, autoreconfHook }:
+
+assert guileSupport -> ( guile != null );
+
+let
+  version = "4.2.90";
+  revision = "48c8a116a914a325a0497721f5d8b58d5bba34d4";
+  revCount = "2491";
+  shortRev = "48c8a11";
+
+  baseVersion = "4.2.1";
+  baseTarball = fetchurl {
+    url = "mirror://gnu/make/make-${baseVersion}.tar.bz2";
+    sha256 = "12f5zzyq2w56g95nni65hc0g5p7154033y2f3qmjvd016szn5qnn";
+  };
+in
+stdenv.mkDerivation {
+  name = "gnumake-${version}pre${revCount}_${shortRev}";
+
+  src = fetchurl {
+    url = "http://git.savannah.gnu.org/cgit/make.git/snapshot/make-${revision}.tar.gz";
+    sha256 = "0k6yvhr2a5lh1qhflv02dyvq5p20ikgaakm8w6gr4xmkspljwpwx";
+  };
+
+  postUnpack = ''
+    unpackFile ${baseTarball}
+    cp make-${baseVersion}/po/*.po $sourceRoot/po
+    cp make-${baseVersion}/doc/{fdl,make-stds}.texi $sourceRoot/doc
+  '';
+
+  patches = [
+    # Purity: don't look for library dependencies (of the form `-lfoo') in /lib
+    # and /usr/lib. It's a stupid feature anyway. Likewise, when searching for
+    # included Makefiles, don't look in /usr/include and friends.
+    ./impure-dirs-head.patch
+  ];
+
+  postPatch = ''
+    # These aren't in the 4.2.1 tarball yet.
+    sed -i -e 's/sr//' -e 's/zh_TW//' po/LINGUAS
+  '';
+
+  nativeBuildInputs = [ autoreconfHook pkgconfig texinfo ];
+  buildInputs = stdenv.lib.optional guileSupport guile;
+
+  configureFlags = stdenv.lib.optional guileSupport "--with-guile";
+
+  outputs = [ "out" "man" "info" ];
+
+  meta = with stdenv.lib; {
+    homepage = http://www.gnu.org/software/make/;
+    description = "A tool to control the generation of non-source files from sources";
+    license = licenses.gpl3Plus;
+
+    longDescription = ''
+      Make is a tool which controls the generation of executables and
+      other non-source files of a program from the program's source files.
+
+      Make gets its knowledge of how to build your program from a file
+      called the makefile, which lists each of the non-source files and
+      how to compute it from other files. When you write a program, you
+      should write a makefile for it, so that it is possible to use Make
+      to build and install the program.
+    '';
+
+    platforms = platforms.all;
+    maintainers = [ maintainers.vrthra ];
+  };
+}
diff --git a/pkgs/development/tools/build-managers/gnumake/4.2/impure-dirs-head.patch b/pkgs/development/tools/build-managers/gnumake/4.2/impure-dirs-head.patch
new file mode 100644
index 000000000000..06d39e13ce39
--- /dev/null
+++ b/pkgs/development/tools/build-managers/gnumake/4.2/impure-dirs-head.patch
@@ -0,0 +1,31 @@
+diff -Naur a/src/read.c b/src/read.c
+--- a/src/read.c	2017-11-19 15:17:47.000000000 -0500
++++ b/src/read.c	2018-02-19 08:53:51.548755213 -0500
+@@ -109,10 +109,12 @@
+ #endif
+     INCLUDEDIR,
+ #ifndef _AMIGA
++#if 0
+     "/usr/gnu/include",
+     "/usr/local/include",
+     "/usr/include",
+ #endif
++#endif
+     0
+   };
+ 
+diff -Naur a/src/remake.c b/src/remake.c
+--- a/src/remake.c	2017-11-19 15:17:47.000000000 -0500
++++ b/src/remake.c	2018-02-19 08:54:08.304101943 -0500
+@@ -1601,9 +1601,11 @@
+   static const char *dirs[] =
+     {
+ #ifndef _AMIGA
++#if 0
+       "/lib",
+       "/usr/lib",
+ #endif
++#endif
+ #if defined(WINDOWS32) && !defined(LIBDIR)
+ /*
+  * This is completely up to the user at product install time. Just define
diff --git a/pkgs/development/tools/misc/binutils/2.30.nix b/pkgs/development/tools/misc/binutils/2.30.nix
new file mode 100644
index 000000000000..830c07330524
--- /dev/null
+++ b/pkgs/development/tools/misc/binutils/2.30.nix
@@ -0,0 +1,131 @@
+{ stdenv, buildPackages
+, fetchurl, zlib
+, buildPlatform, hostPlatform, targetPlatform
+, noSysDirs, gold ? true, bison ? null
+}:
+
+let
+  version = "2.30";
+  basename = "binutils-${version}";
+  inherit (stdenv.lib) optional optionals optionalString;
+  # The targetPrefix prepended to binary names to allow multiple binuntils on the
+  # PATH to both be usable.
+  targetPrefix = optionalString (targetPlatform != hostPlatform) "${targetPlatform.config}-";
+in
+
+stdenv.mkDerivation rec {
+  name = targetPrefix + basename;
+
+  src = fetchurl {
+    url = "mirror://gnu/binutils/${basename}.tar.bz2";
+    sha256 = "028cklfqaab24glva1ks2aqa1zxa6w6xmc8q34zs1sb7h22dxspg";
+  };
+
+  patches = [
+    # Turn on --enable-new-dtags by default to make the linker set
+    # RUNPATH instead of RPATH on binaries.  This is important because
+    # RUNPATH can be overriden using LD_LIBRARY_PATH at runtime.
+    ./new-dtags.patch
+
+    # Since binutils 2.22, DT_NEEDED flags aren't copied for dynamic outputs.
+    # That requires upstream changes for things to work. So we can patch it to
+    # get the old behaviour by now.
+    ./dtneeded.patch
+
+    # Make binutils output deterministic by default.
+    ./deterministic.patch
+
+    # Always add PaX flags section to ELF files.
+    # This is needed, for instance, so that running "ldd" on a binary that is
+    # PaX-marked to disable mprotect doesn't fail with permission denied.
+    ./pt-pax-flags.patch
+
+    # Bfd looks in BINDIR/../lib for some plugins that don't
+    # exist. This is pointless (since users can't install plugins
+    # there) and causes a cycle between the lib and bin outputs, so
+    # get rid of it.
+    ./no-plugins.patch
+
+    # Help bfd choose between elf32-littlearm, elf32-littlearm-symbian, and
+    # elf32-littlearm-vxworks in favor of the first.
+    # https://github.com/NixOS/nixpkgs/pull/30484#issuecomment-345472766
+    ./disambiguate-arm-targets.patch
+
+    # For some reason bfd ld doesn't search DT_RPATH when cross-compiling. It's
+    # not clear why this behavior was decided upon but it has the unfortunate
+    # consequence that the linker will fail to find transitive dependencies of
+    # shared objects when cross-compiling. Consequently, we are forced to
+    # override this behavior, forcing ld to search DT_RPATH even when
+    # cross-compiling.
+    ./always-search-rpath.patch
+  ];
+
+  outputs = [ "out" "info" "man" ];
+
+  depsBuildBuild = [ buildPackages.stdenv.cc ];
+  nativeBuildInputs = [ bison ];
+  buildInputs = [ zlib ];
+
+  inherit noSysDirs;
+
+  preConfigure = ''
+    # Clear the default library search path.
+    if test "$noSysDirs" = "1"; then
+        echo 'NATIVE_LIB_DIRS=' >> ld/configure.tgt
+    fi
+
+    # Use symlinks instead of hard links to save space ("strip" in the
+    # fixup phase strips each hard link separately).
+    for i in binutils/Makefile.in gas/Makefile.in ld/Makefile.in gold/Makefile.in; do
+        sed -i "$i" -e 's|ln |ln -s |'
+    done
+  '';
+
+  # As binutils takes part in the stdenv building, we don't want references
+  # to the bootstrap-tools libgcc (as uses to happen on arm/mips)
+  NIX_CFLAGS_COMPILE = if hostPlatform.isDarwin
+    then "-Wno-string-plus-int -Wno-deprecated-declarations"
+    else "-static-libgcc";
+
+  # TODO(@Ericson2314): Always pass "--target" and always targetPrefix.
+  configurePlatforms =
+    # TODO(@Ericson2314): Figure out what's going wrong with Arm
+    if buildPlatform == hostPlatform && hostPlatform == targetPlatform && targetPlatform.isArm
+    then []
+    else [ "build" "host" ] ++ stdenv.lib.optional (targetPlatform != hostPlatform) "target";
+
+  configureFlags = [
+    "--enable-targets=all" "--enable-64-bit-bfd"
+    "--disable-install-libbfd"
+    "--disable-shared" "--enable-static"
+    "--with-system-zlib"
+
+    "--enable-deterministic-archives"
+    "--disable-werror"
+    "--enable-fix-loongson2f-nop"
+  ] ++ optionals gold [ "--enable-gold" "--enable-plugins" ];
+
+  enableParallelBuilding = true;
+
+  passthru = {
+    inherit targetPrefix version;
+  };
+
+  meta = with stdenv.lib; {
+    description = "Tools for manipulating binaries (linker, assembler, etc.)";
+    longDescription = ''
+      The GNU Binutils are a collection of binary tools.  The main
+      ones are `ld' (the GNU linker) and `as' (the GNU assembler).
+      They also include the BFD (Binary File Descriptor) library,
+      `gprof', `nm', `strip', etc.
+    '';
+    homepage = http://www.gnu.org/software/binutils/;
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ ericson2314 ];
+    platforms = platforms.unix;
+
+    /* Give binutils a lower priority than gcc-wrapper to prevent a
+       collision due to the ld/as wrappers/symlinks in the latter. */
+    priority = 10;
+  };
+}
diff --git a/pkgs/misc/riscv-pk/default.nix b/pkgs/misc/riscv-pk/default.nix
index 025d591d137a..5f0d1fa438f4 100644
--- a/pkgs/misc/riscv-pk/default.nix
+++ b/pkgs/misc/riscv-pk/default.nix
@@ -1,4 +1,4 @@
-{ stdenv, fetchFromGitHub, autoreconfHook }: let
+{ stdenv, fetchFromGitHub, autoreconfHook, payload ? null }: let
   rev = "e5846a2bc707eaa58dc8ab6a8d20a090c6ee8570";
   sha256 = "1clynpp70fnbgsjgxx7xi0vrdrj1v0h8zpv0x26i324kp2gwylf4";
   revCount = "438";
@@ -21,6 +21,9 @@ in stdenv.mkDerivation {
 
   configureScript = "../configure";
 
+  configureFlags = stdenv.lib.optional (payload != null)
+    "--with-payload=${payload}";
+
   hardeningDisable = [ "all" ];
 
   meta = {
diff --git a/pkgs/os-specific/linux/kernel/linux-riscv.nix b/pkgs/os-specific/linux/kernel/linux-riscv.nix
new file mode 100644
index 000000000000..b2eb0a69a8ec
--- /dev/null
+++ b/pkgs/os-specific/linux/kernel/linux-riscv.nix
@@ -0,0 +1,18 @@
+{ stdenv, buildPackages, hostPlatform, fetchFromGitHub, perl, buildLinux, libelf, utillinux, ... } @ args:
+
+buildLinux (args // rec {
+  version = "4.16-rc1";
+  modDirVersion = "4.16.0-rc1";
+  extraMeta.branch = "4.16";
+
+  src = fetchFromGitHub {
+    owner = "riscv";
+    repo ="riscv-linux";
+    rev = "a31991a9c6ce2c86fd676cf458a0ec10edc20d37";
+    sha256 = "0n97wfbi3pnp5c70xfj7s0fk8zjjkjz6ldxh7n54kbf64l4in01f";
+  };
+
+  # Should the testing kernels ever be built on Hydra?
+  extraMeta.hydraPlatforms = [];
+
+} // (args.argsOverride or {}))
diff --git a/pkgs/os-specific/linux/kernel/patches.nix b/pkgs/os-specific/linux/kernel/patches.nix
index 754a2372c6d8..39af0a679361 100644
--- a/pkgs/os-specific/linux/kernel/patches.nix
+++ b/pkgs/os-specific/linux/kernel/patches.nix
@@ -72,4 +72,20 @@ rec {
       sha256 = "09096npxpgvlwdz3pb3m9brvxh7vy0xc9z9p8hh85xyczyzcsjhr";
     };
   };
+
+  riscv_modules = {
+    name = "riscv-modules";
+    patch = ./riscv-modules.patch;
+  };
+
+  riscv_irq_busy = {
+    name = "riscv-irq-busy";
+    patch = ./riscv-irq-busy.patch;
+  };
+
+  riscv_install = {
+    name = "riscv-install";
+    patch = ./riscv-install.patch;
+  };
+
 }
diff --git a/pkgs/os-specific/linux/kernel/riscv-install.patch b/pkgs/os-specific/linux/kernel/riscv-install.patch
new file mode 100644
index 000000000000..707230e9a336
--- /dev/null
+++ b/pkgs/os-specific/linux/kernel/riscv-install.patch
@@ -0,0 +1,65 @@
+commit 365fc1312f4911bfae25c5914c398f9aca21948f
+Author: Shea Levy <shea@shealevy.com>
+Date:   Mon Feb 19 10:50:58 2018 -0500
+
+    riscv: Add install target to Makefile.
+    
+    Signed-off-by: Shea Levy <shea@shealevy.com>
+
+diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
+index 6719dd30ec5b..26892daefa05 100644
+--- a/arch/riscv/Makefile
++++ b/arch/riscv/Makefile
+@@ -70,3 +70,7 @@ core-y += arch/riscv/kernel/ arch/riscv/mm/
+ libs-y += arch/riscv/lib/
+ 
+ all: vmlinux
++
++PHONY += install
++install: vmlinux
++	sh $(srctree)/arch/riscv/install.sh $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)"
+diff --git a/arch/riscv/install.sh b/arch/riscv/install.sh
+new file mode 100644
+index 000000000000..8b3155a11a4a
+--- /dev/null
++++ b/arch/riscv/install.sh
+@@ -0,0 +1,39 @@
++#!/bin/sh
++#
++# arch/riscv/install.sh
++#
++# This file is subject to the terms and conditions of the GNU General Public
++# License.  See the file "COPYING" in the main directory of this archive
++# for more details.
++#
++# Copyright (C) 1995 by Linus Torvalds
++#
++# Adapted from code in arch/ia64/Makefile by Shea Levy
++#
++# "make install" script for riscv architecture
++#
++# Arguments:
++#   $1 - kernel version
++#   $2 - kernel image file
++#   $3 - kernel map file
++#   $4 - default install path (blank if root directory)
++#
++
++# User may have a custom install script
++
++if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
++if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
++
++# Default install - no bootloader configuration (yet?)
++base=$(basename $2)
++
++if [ -f $4/$base ]; then
++	mv $4/$base $4/$base.old
++fi
++
++if [ -f $4/System.map ]; then
++	mv $4/System.map $4/System.old
++fi
++
++cat $2 > $4/$base
++cp $3 $4/System.map
diff --git a/pkgs/os-specific/linux/kernel/riscv-irq-busy.patch b/pkgs/os-specific/linux/kernel/riscv-irq-busy.patch
new file mode 100644
index 000000000000..5f5e8f0c8b7b
--- /dev/null
+++ b/pkgs/os-specific/linux/kernel/riscv-irq-busy.patch
@@ -0,0 +1,42 @@
+commit 2603e6087b26e9428b806b267aee6bcb919abcea
+Author: Shea Levy <shea@shealevy.com>
+Date:   Sun Feb 18 20:08:30 2018 -0500
+
+    set_handle_irq: Return EBUSY if the handler has already been registered.
+    
+    This is what's expected by the comments and at least by irq-riscv-intc.c
+    
+    Signed-off-by: Shea Levy <shea@shealevy.com>
+
+diff --git a/include/linux/irq.h b/include/linux/irq.h
+index 2930fd2572e4..77e97872a13e 100644
+--- a/include/linux/irq.h
++++ b/include/linux/irq.h
+@@ -1179,7 +1179,7 @@ int ipi_send_mask(unsigned int virq, const struct cpumask *dest);
+  * Returns 0 on success, or -EBUSY if an IRQ handler has already been
+  * registered.
+  */
+-void __init set_handle_irq(void (*handle_irq)(struct pt_regs *));
++int __init set_handle_irq(void (*handle_irq)(struct pt_regs *));
+ 
+ /*
+  * Allows interrupt handlers to find the irqchip that's been registered as the
+diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
+index dee4f9a172ca..3570c715c3e7 100644
+--- a/kernel/irq/handle.c
++++ b/kernel/irq/handle.c
+@@ -213,11 +213,12 @@ irqreturn_t handle_irq_event(struct irq_desc *desc)
+ }
+ 
+ #ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
+-void __init set_handle_irq(void (*handle_irq)(struct pt_regs *))
++int __init set_handle_irq(void (*handle_irq)(struct pt_regs *))
+ {
+ 	if (handle_arch_irq)
+-		return;
++		return -EBUSY;
+ 
+ 	handle_arch_irq = handle_irq;
++	return 0;
+ }
+ #endif
diff --git a/pkgs/os-specific/linux/kernel/riscv-modules.patch b/pkgs/os-specific/linux/kernel/riscv-modules.patch
new file mode 100644
index 000000000000..6d5356e0e46f
--- /dev/null
+++ b/pkgs/os-specific/linux/kernel/riscv-modules.patch
@@ -0,0 +1,11 @@
+diff -Naur linux-4.15.4-orig/arch/riscv/configs/defconfig linux-4.15.4/arch/riscv/configs/defconfig
+--- linux-4.15.4-orig/arch/riscv/configs/defconfig	2018-02-16 14:07:01.000000000 -0500
++++ linux-4.15.4/arch/riscv/configs/defconfig	2018-02-18 18:33:09.488431900 -0500
+@@ -12,6 +12,7 @@
+ CONFIG_NAMESPACES=y
+ CONFIG_USER_NS=y
+ CONFIG_BLK_DEV_INITRD=y
++CONFIG_MODULES=y
+ CONFIG_EXPERT=y
+ CONFIG_CHECKPOINT_RESTORE=y
+ CONFIG_BPF_SYSCALL=y
diff --git a/pkgs/os-specific/linux/powertop/default.nix b/pkgs/os-specific/linux/powertop/default.nix
index 5a10f455ea06..7679262a9899 100644
--- a/pkgs/os-specific/linux/powertop/default.nix
+++ b/pkgs/os-specific/linux/powertop/default.nix
@@ -9,6 +9,8 @@ stdenv.mkDerivation rec {
     sha256 = "0l4jjlf05li2mc6g8nrss3h435wjhmnqd8m7v3kha3x0x7cbfzxa";
   };
 
+  outputs = [ "out" "man" ];
+
   nativeBuildInputs = [ pkgconfig ];
   buildInputs = [ gettext libnl ncurses pciutils zlib ];
 
diff --git a/pkgs/stdenv/darwin/default.nix b/pkgs/stdenv/darwin/default.nix
index 28b2f203dae5..27b3c176a2a7 100644
--- a/pkgs/stdenv/darwin/default.nix
+++ b/pkgs/stdenv/darwin/default.nix
@@ -118,6 +118,7 @@ in rec {
         initialPath  = [ bootstrapTools ];
 
         fetchurlBoot = import ../../build-support/fetchurl {
+          inherit lib;
           stdenvNoCC = stage0.stdenv;
           curl = bootstrapTools;
         };
diff --git a/pkgs/stdenv/freebsd/default.nix b/pkgs/stdenv/freebsd/default.nix
index 6ab8bf217269..b3a6cedad841 100644
--- a/pkgs/stdenv/freebsd/default.nix
+++ b/pkgs/stdenv/freebsd/default.nix
@@ -29,7 +29,8 @@ let inherit (localSystem) system; in
     inherit bootstrapTools;
 
     fetchurl = import ../../build-support/fetchurl {
-      inherit stdenv;
+      inherit lib;
+      stdenvNoCC = stdenv;
       curl = bootstrapTools;
     };
 
diff --git a/pkgs/stdenv/generic/check-meta.nix b/pkgs/stdenv/generic/check-meta.nix
index dc5e79fcd4f2..93d0f4cc9805 100644
--- a/pkgs/stdenv/generic/check-meta.nix
+++ b/pkgs/stdenv/generic/check-meta.nix
@@ -159,7 +159,7 @@ let
     executables = listOf str;
     outputsToInstall = listOf str;
     position = str;
-    evaluates = bool;
+    available = bool;
     repositories = attrsOf str;
     isBuildPythonPackage = platforms;
     schedulingPriority = int;
diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix
index e021b284a122..e8f78d7401f1 100644
--- a/pkgs/stdenv/generic/make-derivation.nix
+++ b/pkgs/stdenv/generic/make-derivation.nix
@@ -238,9 +238,9 @@ rec {
           position = pos.file + ":" + toString pos.line;
         # Expose the result of the checks for everyone to see.
         } // {
-          evaluates = validity.valid
+          available = validity.valid
                    && (if config.checkMetaRecursively or false
-                       then lib.all (d: d.meta.evaluates or true) references
+                       then lib.all (d: d.meta.available or true) references
                        else true);
         };
 
diff --git a/pkgs/stdenv/native/default.nix b/pkgs/stdenv/native/default.nix
index 558a77281edb..19efac3700a6 100644
--- a/pkgs/stdenv/native/default.nix
+++ b/pkgs/stdenv/native/default.nix
@@ -131,7 +131,7 @@ in
     };
 
     fetchurl = import ../../build-support/fetchurl {
-      inherit stdenv;
+      inherit lib stdenvNoCC;
       # Curl should be in /usr/bin or so.
       curl = null;
     };
diff --git a/pkgs/tools/package-management/nix/default.nix b/pkgs/tools/package-management/nix/default.nix
index f6e6988270ad..e45858eb3bb8 100644
--- a/pkgs/tools/package-management/nix/default.nix
+++ b/pkgs/tools/package-management/nix/default.nix
@@ -126,12 +126,12 @@ in rec {
 
   nixUnstable = (lib.lowPrio (common rec {
     name = "nix-2.0${suffix}";
-    suffix = "pre5951_690ac7c9";
+    suffix = "pre5967_623fcb07";
     src = fetchFromGitHub {
       owner = "NixOS";
       repo = "nix";
-      rev = "690ac7c90b5bf3c599e210c53365c7d229c8b0ff";
-      sha256 = "1yn2p38kp1i67makbawr1rhdiwihgnvk2zwrz0gvf6q65mj2k89c";
+      rev = "623fcb071e1440a995d8ebcd769d67a45a439711";
+      sha256 = "0gk9963dbz53n5cmm546vnibmnlzcwsp8bmfsrwgx9kb0qzzvym9";
     };
     fromGit = true;
   })) // { perl-bindings = perl-bindings { nix = nixUnstable; }; };
diff --git a/pkgs/tools/security/afl/default.nix b/pkgs/tools/security/afl/default.nix
index 51701590b8e9..1ff0ad6f6b68 100644
--- a/pkgs/tools/security/afl/default.nix
+++ b/pkgs/tools/security/afl/default.nix
@@ -20,7 +20,7 @@ stdenv.mkDerivation rec {
 
   # Note: libcgroup isn't needed for building, just for the afl-cgroup
   # script.
-  buildInputs  = [ makeWrapper clang llvm which ];
+  buildInputs  = [ makeWrapper llvm which ];
 
   buildPhase   = ''
     make PREFIX=$out
@@ -53,8 +53,7 @@ stdenv.mkDerivation rec {
     for x in $out/bin/afl-clang-fast $out/bin/afl-clang-fast++; do
       wrapProgram $x \
         --prefix AFL_PATH : "$out/lib/afl" \
-        --prefix AFL_CC   : "${clang}/bin/clang" \
-        --prefix AFL_CXX  : "${clang}/bin/clang++"
+        --run 'export AFL_CC=''${AFL_CC:-${clang}/bin/clang} AFL_CXX=''${AFL_CXX:-${clang}/bin/clang++}'
     done
   '';
 
@@ -76,7 +75,7 @@ stdenv.mkDerivation rec {
     '';
     homepage    = "http://lcamtuf.coredump.cx/afl/";
     license     = stdenv.lib.licenses.asl20;
-    platforms   = stdenv.lib.platforms.linux;
+    platforms   = ["x86_64-linux" "i686-linux"];
     maintainers = [ stdenv.lib.maintainers.thoughtpolice ];
   };
 }
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 046db0c66cce..3b6f28a66b33 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -195,7 +195,7 @@ with pkgs;
 
   # `fetchurl' downloads a file from the network.
   fetchurl = import ../build-support/fetchurl {
-    inherit stdenvNoCC;
+    inherit lib stdenvNoCC;
     # On darwin, libkrb5 needs bootstrap_cmds which would require
     # converting many packages to fetchurl_boot to avoid evaluation cycles.
     curl = buildPackages.curl.override (lib.optionalAttrs stdenv.isDarwin { gssSupport = false; });
@@ -7322,6 +7322,8 @@ with pkgs;
   binutils =
     if targetPlatform.isDarwin
     then darwin.binutils
+    else if targetPlatform.isRiscV
+    then binutils_2_30
     else binutils-raw;
 
   binutils-unwrapped = callPackage ../development/tools/misc/binutils {
@@ -7332,6 +7334,15 @@ with pkgs;
     libc = if targetPlatform != hostPlatform then libcCross else stdenv.cc.libc;
     bintools = binutils-unwrapped;
   };
+  binutils-unwrapped_2_30 = callPackage ../development/tools/misc/binutils/2.30.nix {
+    # FHS sys dirs presumably only have stuff for the build platform
+    noSysDirs = (targetPlatform != buildPlatform) || noSysDirs;
+  };
+  binutils-raw_2_30 = wrapBintoolsWith {
+    libc = if targetPlatform != hostPlatform then libcCross else stdenv.cc.libc;
+    bintools = binutils-unwrapped_2_30;
+  };
+  binutils_2_30 = binutils-raw_2_30;
 
   binutils_nogold = lowPrio (binutils-raw.override {
     bintools = binutils-raw.bintools.override {
@@ -7650,7 +7661,10 @@ with pkgs;
   gnumake382 = callPackage ../development/tools/build-managers/gnumake/3.82 { };
   gnumake3 = gnumake382;
   gnumake42 = callPackage ../development/tools/build-managers/gnumake/4.2 { };
-  gnumake = gnumake42;
+  gnumake = if hostPlatform.isRiscV # Technically this check should be for glibc version.
+    then gnumake42HEAD
+  else gnumake42;
+  gnumake42HEAD = callPackage ../development/tools/build-managers/gnumake/4.2/head.nix { };
 
   gnustep = recurseIntoAttrs (callPackage ../desktops/gnustep {});
 
@@ -13093,6 +13107,13 @@ with pkgs;
       ];
   };
 
+  linux_riscv = callPackage ../os-specific/linux/kernel/linux-riscv.nix {
+    kernelPatches = [
+      kernelPatches.bridge_stp_helper
+      kernelPatches.modinst_arg_list_too_long
+    ] ++ lib.optionals hostPlatform.isRiscV [ kernelPatches.riscv_modules kernelPatches.riscv_irq_busy kernelPatches.riscv_install ];
+  };
+
   linux_samus_4_12 = callPackage ../os-specific/linux/kernel/linux-samus-4.12.nix {
     kernelPatches =
       [ kernelPatches.bridge_stp_helper
@@ -13544,6 +13565,10 @@ with pkgs;
 
   riscv-pk = callPackage ../misc/riscv-pk { };
 
+  riscv-pk-with-kernel = riscv-pk.override {
+    payload = "${linux_riscv}/vmlinux";
+  };
+
   rtkit = callPackage ../os-specific/linux/rtkit { };
 
   rt5677-firmware = callPackage ../os-specific/linux/firmware/rt5677 { };
diff --git a/pkgs/top-level/ocaml-packages.nix b/pkgs/top-level/ocaml-packages.nix
index 1fffa3fa800b..10eb72da19eb 100644
--- a/pkgs/top-level/ocaml-packages.nix
+++ b/pkgs/top-level/ocaml-packages.nix
@@ -60,6 +60,8 @@ let
 
     bitstring = callPackage ../development/ocaml-modules/bitstring { };
 
+    bitv = callPackage ../development/ocaml-modules/bitv { };
+
     bolt = callPackage ../development/ocaml-modules/bolt { };
 
     bos = callPackage ../development/ocaml-modules/bos { };