On 9/25/25 05:55, Alyssa Ross wrote: > Yureka Lilian writes: > >> The xdp-forwarder's purpose is implementing the functionality needed >> within the net-vm (a VM running the Linux drivers for any physical >> interfaces on the spectrum system). >> >> In the future, the net-vm will load the included XDP programs on the >> passed-through physical interfaces as well as the downstream virtio >> interface going into the router (recognized by its special MAC address). >> >> The net-vm needs to multiplex between the physical interfaces, as there >> might be several interfaces in the same IOMMU-group. >> >> For this, the XDP program loaded on the physical interfaces >> (`prog_physical.o`) applies a VLAN tag corresponding to the interface id >> and redirects the packets to the router interface (identified by the >> `router_iface` bpf map). In the other direction the XDP program loaded on >> the router interface (`prog_router.o`) removes one layer of VLAN tagging >> and redirects the packets to the interface read from the VLAN tag. >> >> The helper program `set_router_iface` is used to update the `router_iface` >> bpf map to point to the interface passed as argument to the program. >> >> Co-authored-by: Demi Marie Obenour >> Signed-off-by: Yureka Lilian >> Signed-off-by: Demi Marie Obenour >> --- >> pkgs/default.nix | 4 + >> release/checks/pkg-tests.nix | 1 + >> tools/default.nix | 21 +- >> tools/meson.build | 4 + >> tools/meson_options.txt | 3 + >> tools/xdp-forwarder/meson.build | 48 +++++ >> tools/xdp-forwarder/parsing_helpers.h | 274 +++++++++++++++++++++++++ >> tools/xdp-forwarder/prog_physical.c | 39 ++++ >> tools/xdp-forwarder/prog_router.c | 42 ++++ >> tools/xdp-forwarder/rewrite_helpers.h | 146 +++++++++++++ >> tools/xdp-forwarder/set_router_iface.c | 30 +++ >> 11 files changed, 608 insertions(+), 4 deletions(-) >> create mode 100644 tools/xdp-forwarder/meson.build >> create mode 100644 tools/xdp-forwarder/parsing_helpers.h >> create mode 100644 tools/xdp-forwarder/prog_physical.c >> create mode 100644 tools/xdp-forwarder/prog_router.c >> create mode 100644 tools/xdp-forwarder/rewrite_helpers.h >> create mode 100644 tools/xdp-forwarder/set_router_iface.c >> >> diff --git a/pkgs/default.nix b/pkgs/default.nix >> index 2472218..df3cfdc 100644 >> --- a/pkgs/default.nix >> +++ b/pkgs/default.nix >> @@ -42,6 +42,10 @@ let >> appSupport = false; >> hostSupport = true; >> }; >> + spectrum-driver-tools = self.callSpectrumPackage ../tools { >> + appSupport = false; >> + driverSupport = true; >> + }; >> xdg-desktop-portal-spectrum-host = >> self.callSpectrumPackage ../tools/xdg-desktop-portal-spectrum-host {}; >> >> diff --git a/release/checks/pkg-tests.nix b/release/checks/pkg-tests.nix >> index d7be42b..b1a048f 100644 >> --- a/release/checks/pkg-tests.nix >> +++ b/release/checks/pkg-tests.nix >> @@ -14,5 +14,6 @@ import ../../lib/call-package.nix ( >> tools = lib.recurseIntoAttrs (callSpectrumPackage ../../tools { >> appSupport = true; >> hostSupport = true; >> + driverSupport = true; >> }).tests; >> }) (_: {}) >> diff --git a/tools/default.nix b/tools/default.nix >> index 201afae..0e43997 100644 >> --- a/tools/default.nix >> +++ b/tools/default.nix >> @@ -1,13 +1,17 @@ >> # SPDX-License-Identifier: MIT >> # SPDX-FileCopyrightText: 2022-2025 Alyssa Ross >> +# SPDX-FileCopyrightText: 2025 Yureka Lilian >> >> import ../lib/call-package.nix ( >> { src, lib, stdenv, fetchCrate, fetchurl, runCommand, buildPackages >> , meson, ninja, pkg-config, rustc >> , clang-tools, clippy >> , dbus >> +# clang 19 (current nixpkgs default) is too old to support -fwrapv-pointer >> +, clang_21, libbpf >> , appSupport ? true >> , hostSupport ? false >> +, driverSupport ? false >> }: >> >> let >> @@ -70,15 +74,18 @@ stdenv.mkDerivation (finalAttrs: { >> ./lsvm >> ./start-vmm >> ./subprojects >> + ] ++ lib.optionals driverSupport [ >> + ./xdp-forwarder >> ])); >> }; >> sourceRoot = "source/tools"; >> >> depsBuildBuild = lib.optionals hostSupport [ buildPackages.stdenv.cc ]; >> nativeBuildInputs = [ meson ninja ] >> - ++ lib.optionals appSupport [ pkg-config ] >> - ++ lib.optionals hostSupport [ rustc ]; >> - buildInputs = lib.optionals appSupport [ dbus ]; >> + ++ lib.optionals (appSupport || driverSupport) [ pkg-config ] >> + ++ lib.optionals hostSupport [ rustc ] >> + ++ lib.optionals driverSupport [ clang_21 ]; >> + buildInputs = lib.optionals appSupport [ dbus ] ++ lib.optionals driverSupport [ libbpf ]; >> >> postPatch = lib.optionals hostSupport (lib.concatMapStringsSep "\n" (crate: '' >> mkdir -p subprojects/packagecache >> @@ -88,12 +95,16 @@ stdenv.mkDerivation (finalAttrs: { >> mesonFlags = [ >> (lib.mesonBool "app" appSupport) >> (lib.mesonBool "host" hostSupport) >> + (lib.mesonBool "driver" driverSupport) >> "-Dhostfsrootdir=/run/virtiofs/virtiofs0" >> "-Dtests=false" >> "-Dunwind=false" >> "-Dwerror=true" >> ]; >> >> + # Not supported for target bpf >> + hardeningDisable = lib.optionals driverSupport [ "zerocallusedregs" ]; >> + >> passthru.tests = { >> clang-tidy = finalAttrs.finalPackage.overrideAttrs ( >> { name, src, nativeBuildInputs ? [], ... }: >> @@ -105,7 +116,9 @@ stdenv.mkDerivation (finalAttrs: { >> fileset = lib.fileset.union (lib.fileset.fromSource src) ../.clang-tidy; >> }; >> >> - nativeBuildInputs = nativeBuildInputs ++ [ clang-tools ]; >> + # clang-tools needs to be before clang, otherwise it will not use >> + # the Nix include path correctly and fail to find headers >> + nativeBuildInputs = [ clang-tools ] ++ nativeBuildInputs; >> >> buildPhase = '' >> clang-tidy --warnings-as-errors='*' ../**/*.c >> diff --git a/tools/meson.build b/tools/meson.build >> index e8b0cf2..059baeb 100644 >> --- a/tools/meson.build >> +++ b/tools/meson.build >> @@ -26,3 +26,7 @@ endif >> if get_option('app') >> subdir('xdg-desktop-portal-spectrum') >> endif >> + >> +if get_option('driver') >> + subdir('xdp-forwarder') >> +endif >> diff --git a/tools/meson_options.txt b/tools/meson_options.txt >> index fb520ae..7b46739 100644 >> --- a/tools/meson_options.txt >> +++ b/tools/meson_options.txt >> @@ -7,6 +7,9 @@ option('host', type : 'boolean', value : false, >> option('app', type : 'boolean', >> description : 'Build tools for Spectrum app VMs') >> >> +option('driver', type : 'boolean', value : false, >> + description : 'Build tools for Spectrum driver VMs') >> + >> option('hostfsrootdir', type : 'string', value : '/run/host', >> description : 'Path where the virtio-fs provided by the host will be mounted') >> >> diff --git a/tools/xdp-forwarder/meson.build b/tools/xdp-forwarder/meson.build >> new file mode 100644 >> index 0000000..9b70ce3 >> --- /dev/null >> +++ b/tools/xdp-forwarder/meson.build >> @@ -0,0 +1,48 @@ >> +# SPDX-License-Identifier: EUPL-1.2+ >> +# SPDX-FileCopyrightText: 2025 Yureka Lilian >> +# SPDX-FileCopyrightText: 2025 Demi Marie Obenour >> + >> +libbpf = dependency('libbpf', version : '1.6.2') >> + >> +executable('set-router-iface', 'set_router_iface.c', >> + dependencies : libbpf, >> + install : true) >> + >> +clang = find_program('clang', native: true) >> + >> +bpf_o_cmd = [ >> + clang.full_path(), >> + '-fno-stack-protector', >> + '-fno-strict-aliasing', >> + '-fwrapv', '-fwrapv-pointer', >> + '-Wall', >> + '-Wextra', >> + '-O2', >> + '-target', 'bpf', >> + '-I', meson.current_source_dir() + '/include', >> + '-g', >> + '-c', >> + '-o', '@OUTPUT@', >> + '-MD', >> + '-MP', >> + '-MF', '@DEPFILE@', > > Demi: you suggested these arguments, but the Meson default is > -MD -MQ $out -MF $DEPFILE, as far as I can tell. > > Why the difference? I didn't know of -MQ. -MP is almost certainly redundant. Go with what Meson recommended. >> + '--', >> + '@INPUT@', >> +] >> + >> +prog_router_o = custom_target( >> + input : 'prog_router.c', >> + output : 'prog_router.o', >> + depfile : 'prog_router.o.dep', >> + command : bpf_o_cmd, >> + install: true, >> + install_dir: 'lib/xdp') >> + >> +prog_physical_o = custom_target( >> + input : 'prog_physical.c', >> + output : 'prog_physical.o', >> + depfile : 'prog_physical.o.dep', >> + command : bpf_o_cmd, >> + install: true, >> + install_dir: 'lib/xdp') >> + -- Sincerely, Demi Marie Obenour (she/her/hers)