From b70c8ee258d89c0ce850d49bea26e0a5c3fdcceb Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Tue, 9 May 2023 22:58:56 +0100 Subject: [PATCH] support USB ethernet in bordervm --- bordervm-configuration.nix | 47 ++++++++++++++++++++++++++------------ bordervm.conf-example.nix | 3 ++- doc/developer.rst | 6 +++-- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/bordervm-configuration.nix b/bordervm-configuration.nix index 6803dea7..29b74d7e 100644 --- a/bordervm-configuration.nix +++ b/bordervm-configuration.nix @@ -1,7 +1,7 @@ { config, pkgs, lib, ... }: let cfg = config.bordervm; - inherit (lib) mkOption mdDoc types; + inherit (lib) mkOption mkEnableOption mdDoc types optional optionals; in { options.bordervm = { l2tp = { @@ -22,14 +22,28 @@ in { }; }; ethernet = { - pciId = mkOption { - description = '' - Host PCI ID (as shown by `lspci`) of the ethernet adaptor - to be used by the VM. This uses VFIO and requires setup - on the emulation host before it will work! - ''; - type = types.str; - example = "04:00.0"; + pci = { + enable = mkEnableOption "passthru PCI ethernet"; + id = mkOption { + description = '' + Host PCI ID (as shown by `lspci`) of the ethernet adaptor + to be used by the VM. This uses VFIO and requires setup + on the emulation host before it will work! + ''; + type = types.str; + example = "04:00.0"; + }; + }; + usb = { + enable = mkEnableOption "passthru USB ethernet"; + vendor = mkOption { + type = types.str; + example = "0x0bda"; + }; + product = mkOption { + type = types.str; + example = "0x8153"; + }; }; }; }; @@ -66,11 +80,16 @@ in { virtualisation = { qemu = { networkingOptions = []; - options = [ - "-device vfio-pci,host=${cfg.ethernet.pciId}" - "-nographic" - "-serial mon:stdio" - ]; + options = [] ++ + optional cfg.ethernet.pci.enable + "-device vfio-pci,host=${cfg.ethernet.pci.id}" ++ + optionals cfg.ethernet.usb.enable [ + "-device usb-ehci,id=ehci" + "-device usb-host,bus=ehci.0,vendorid=${cfg.ethernet.usb.vendor},productid=${cfg.ethernet.usb.product}" + ] ++ [ + "-nographic" + "-serial mon:stdio" + ]; }; sharedDirectories = { liminix = { diff --git a/bordervm.conf-example.nix b/bordervm.conf-example.nix index 0df7434f..a27b0451 100644 --- a/bordervm.conf-example.nix +++ b/bordervm.conf-example.nix @@ -1,7 +1,8 @@ {...}: { bordervm = { - ethernet.pciId = "01:00.0"; + # ethernet.pci = { id = "01:00.0"; enable = true; }; + ethernet.usb = { vendor = "0x0bda"; product = "0x8153"; enable = true; }; l2tp = { host = "l2tp.aa.net.uk"; }; diff --git a/doc/developer.rst b/doc/developer.rst index bc18e2ff..4666c092 100644 --- a/doc/developer.rst +++ b/doc/developer.rst @@ -139,11 +139,13 @@ router from the internet so you can borrow the cable/fibre/DSL. ``bordervm`` is included for this purpose. You will need -* a Linux machine with a spare PCI ethernet card which you can dedicate to Liminix +* a Linux machine with a spare (PCI or USB) ethernet device which you can dedicate to Liminix * an L2TP service such as https://www.aa.net.uk/broadband/l2tp-service/ -You need to configure the Ethernet card for VFIO passthru, then +You need to "hide" the Ethernet device from the host - for PCI this +means configuring it for VFIO passthru; for USB you need to +unload the module(s) it uses. Then you can execute :command:`run-border-vm` in a ``buildEnv`` shell, which starts up QEMU using the NixOS configuration in :file:`bordervm-configuration.nix`.