Skip to content

BBR3 on NixOS ( Solution ) #40

@randomizedcoder

Description

@randomizedcoder

G'day,

If here's any interest, I made a Nix module to add bbr3 to the latest kernel on NixOS.

There are some configurePhase changes required to compile against a pretty new kernel 6.18.3

[das@l2:~]$ cat /proc/sys/net/ipv4/tcp_available_congestion_control
reno cubic bbr3

[das@l2:~]$ uname -a
Linux l2 6.18.3 #1-NixOS SMP PREEMPT_DYNAMIC Fri Jan  2 11:57:31 UTC 2026 x86_64 GNU/Linux

[das@l2:~]$ neofetch
          ▗▄▄▄       ▗▄▄▄▄    ▄▄▄▖            das@l2 
          ▜███▙       ▜███▙  ▟███▛            ------ 
           ▜███▙       ▜███▙▟███▛             OS: NixOS 26.05.20260102.fb7944c (Yarara) x86_64 
            ▜███▙       ▜██████▛              Host: LENOVO 1046 
     ▟█████████████████▙ ▜████▛     ▟▙        Kernel: 6.18.3 
    ▟███████████████████▙ ▜███▙    ▟██▙       Uptime: 6 mins 
           ▄▄▄▄▖           ▜███▙  ▟███▛       Packages: 641 (nix-system), 980 (nix-user) 
          ▟███▛             ▜██▛ ▟███▛        Shell: bash 5.3.3 
         ▟███▛               ▜▛ ▟███▛         Resolution: 3840x2160 
▟███████████▛                  ▟██████████▙   Terminal: /dev/pts/0 
▜██████████▛                  ▟███████████▛   CPU: AMD Ryzen Threadripper PRO 3945WX s (24) @ 4.427GHz 
      ▟███▛ ▟▙               ▟███▛            GPU: AMD ATI Radeon PRO WX 2100 
     ▟███▛ ▟██▙             ▟███▛             Memory: 2725MiB / 128660MiB 
    ▟███▛  ▜███▙           ▝▀▀▀▀
    ▜██▛    ▜███▙ ▜██████████████████▛                                
     ▜▛     ▟████▙ ▜████████████████▛                                 
           ▟██████▙       ▜███▙
          ▟███▛▜███▙       ▜███▙
         ▟███▛  ▜███▙       ▜███▙
         ▝▀▀▀    ▀▀▀▀▘       ▀▀▀▘


[das@l2:~]$ date
Sat Jan  3 04:26:02 PM PST 2026

[das@l2:~]$ 
#
# bbr3-module.nix
#
# Build BBRv3 congestion control from L4S kernel source as out-of-tree module
# Source: https://github.com/L4STeam/linux
#
# BBRv3 is an improved version of BBR with better fairness and L4S awareness
#

{ config, lib, pkgs, ... }:

let
  kernel = config.boot.kernelPackages.kernel;

  # L4S repo commit (testing branch)
  l4sRev = "48b3db6b4a7fd57e2d31db3bb46a3bc6af7bf3ad";

  # BBRv3 module built from L4S kernel source
  bbr3Module = pkgs.stdenv.mkDerivation rec {
    pname = "tcp-bbr3";
    version = "3.0-${kernel.version}";

    src = pkgs.fetchFromGitHub {
      owner = "L4STeam";
      repo = "linux";
      rev = l4sRev;
      hash = "sha256-fqv0xKajFFaVpDuN2B13BpeS6dkjObqAPCEVkJXYN6Q=";
    };

    nativeBuildInputs = kernel.moduleBuildDependencies;

    hardeningDisable = [ "pic" "format" ];

    postUnpack = ''
      # Create a clean build directory
      mkdir -p $TMPDIR/build
      cd $TMPDIR/build
      sourceRoot=$TMPDIR/build
    '';

    configurePhase = ''
      # Copy BBRv3 source to build directory
      cp $src/net/ipv4/tcp_bbr.c tcp_bbr3.c

      # Rename the module to avoid conflict with in-kernel tcp_bbr
      sed -i 's/tcp_bbr_cong_ops/tcp_bbr3_cong_ops/g' tcp_bbr3.c
      sed -i 's/bbr_register/bbr3_register/g' tcp_bbr3.c
      sed -i 's/bbr_unregister/bbr3_unregister/g' tcp_bbr3.c
      sed -i 's/MODULE_DESCRIPTION("TCP BBR/MODULE_DESCRIPTION("TCP BBRv3/g' tcp_bbr3.c

      # Change the registered name to "bbr3"
      sed -i 's/\.name[[:space:]]*=[[:space:]]*"bbr"/.name = "bbr3"/g' tcp_bbr3.c

      # === Kernel API compatibility fixes for 6.18+ ===

      # Fix 1: prandom_u32_max was renamed to get_random_u32_below in kernel 6.2+
      sed -i 's/prandom_u32_max/get_random_u32_below/g' tcp_bbr3.c

      # Fix 2: tso_segs was removed/renamed - the function signature changed
      # Just remove the line since it's optional
      sed -i '/\.tso_segs[[:space:]]*=/d' tcp_bbr3.c

      # Fix 3: cong_control signature changed - need to adapt bbr_main
      # Old: void (*cong_control)(struct sock *sk, const struct rate_sample *rs)
      # New: void (*cong_control)(struct sock *sk, u32 ack, int flag, const struct rate_sample *rs)
      # We create a wrapper function
      sed -i '/^static void bbr_main/,/^{/c\
static void bbr_main_inner(struct sock *sk, const struct rate_sample *rs)\
{' tcp_bbr3.c

      # Add wrapper at end before module registration
      sed -i '/static struct tcp_congestion_ops tcp_bbr3_cong_ops/i\
/* Wrapper for new kernel API */\
static void bbr_main(struct sock *sk, u32 ack, int flag, const struct rate_sample *rs)\
{\
	bbr_main_inner(sk, rs);\
}\
' tcp_bbr3.c

      # Create Kbuild file for out-of-tree build
      echo "obj-m := tcp_bbr3.o" > Kbuild
    '';

    buildPhase = ''
      make -C ${kernel.dev}/lib/modules/${kernel.modDirVersion}/build M=$(pwd) modules
    '';

    installPhase = ''
      runHook preInstall
      mkdir -p $out/lib/modules/${kernel.modDirVersion}/extra
      cp tcp_bbr3.ko $out/lib/modules/${kernel.modDirVersion}/extra/
      runHook postInstall
    '';

    meta = with lib; {
      description = "TCP BBRv3 - Bottleneck Bandwidth and RTT v3 from L4S team";
      homepage = "https://github.com/L4STeam/linux";
      license = licenses.gpl2;
      platforms = platforms.linux;
    };
  };

in {
  options.services.bbr3 = {
    enable = lib.mkEnableOption "BBRv3 congestion control module";
  };

  config = lib.mkIf config.services.bbr3.enable {
    boot.extraModulePackages = [ bbr3Module ];
    boot.kernelModules = [ "tcp_bbr3" ];
  };
}

#
# USAGE:
#
# 1. First, get the correct hash:
#    nix-prefetch-github L4STeam linux --rev 48b3db6b4a7fd57e2d31db3bb46a3bc6af7bf3ad
#
# 2. Replace the placeholder hash above with the actual hash
#
# 3. Add to configuration.nix:
#    imports = [ ./bbr3-module.nix ];
#    services.bbr3.enable = true;
#
# 4. Rebuild:
#    sudo nixos-rebuild switch
#
# 5. Verify:
#    lsmod | grep bbr3
#    cat /proc/sys/net/ipv4/tcp_available_congestion_control
#
# 6. To use BBRv3, add to sysctl.nix:
#    "net.ipv4.tcp_congestion_control" = "bbr3";
#

https://discourse.nixos.org/t/bbr3-tcp-for-nix/73954

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions