diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 6f941cc254ad4..bb81692484062 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -1110,6 +1110,7 @@ in { victoriametrics = handleTest ./victoriametrics {}; vikunja = handleTest ./vikunja.nix {}; virtualbox = handleTestOn ["x86_64-linux"] ./virtualbox.nix {}; + vpp = handleTest ./vpp.nix {}; vscode-remote-ssh = handleTestOn ["x86_64-linux"] ./vscode-remote-ssh.nix {}; vscodium = discoverTests (import ./vscodium.nix); vsftpd = handleTest ./vsftpd.nix {}; diff --git a/nixos/tests/vpp.nix b/nixos/tests/vpp.nix new file mode 100644 index 0000000000000..38477a9ec0347 --- /dev/null +++ b/nixos/tests/vpp.nix @@ -0,0 +1,135 @@ +# This test runs FD.io's VPP and tests routing between two virtual networks. +# Topology is similar to the `nat` test, with a client on one network, a server +# on another, and a VPP-powered router inbetween connecting the two. + +import ./make-test-python.nix ( + { pkgs, lib, ... }: + { + name = "vpp"; + + meta.maintainers = with lib.maintainers; [ romner-set ]; + + nodes = { + client = + { ... }: + { + virtualisation.vlans = [ 1 ]; + networking.interfaces = lib.mkForce { + eth1.ipv6.addresses = [ + { + address = "fd01::2"; + prefixLength = 64; + } + ]; + }; + networking.defaultGateway6 = "fd01::1"; + networking.useDHCP = false; + }; + server = + { ... }: + { + virtualisation.vlans = [ 2 ]; + networking.interfaces = lib.mkForce { + eth1.ipv6.addresses = [ + { + address = "fd02::2"; + prefixLength = 64; + } + ]; + }; + networking.defaultGateway6 = "fd02::1"; + networking.useDHCP = false; + + services.httpd.enable = true; + services.httpd.adminAddr = "foo@example.org"; + + networking.firewall.enable = false; + }; + router = + { config, ... }: + { + virtualisation.vlans = [ + 1 + 2 + ]; + + # Disable netdevs so VPP can take over them + networking.useDHCP = false; + networking.interfaces = lib.mkForce { }; + + # install igb_uio driver + boot.extraModulePackages = with config.boot.kernelPackages; [ dpdk-kmods ]; + + virtualisation.memorySize = 4096; + services.vpp.hugepages = { + autoSetup = true; + count = 1024; + }; + + services.vpp.instances.main = { + enable = true; + kernelModule = "igb_uio"; + settings = { + unix.cli-listen = "/run/vpp/cli.sock"; # override a default value + + plugins = { + # Selectively enable only necessary plugins + plugin.default.disable = true; + plugin."dpdk_plugin.so".enable = true; + }; + + dpdk.dev."0000:00:09.0".name = "vlan1"; + dpdk.dev."0000:00:0a.0".name = "vlan2"; + }; + startupConfig = '' + set int state vlan1 up + set int state vlan2 up + set int ip addr vlan1 fd01::1/64 + set int ip addr vlan2 fd02::1/64 + ''; + }; + + environment.systemPackages = with pkgs; [ vpp ]; + }; + }; + + testScript = '' + start_all() + + # wait for router + router.wait_for_unit("vpp-main.service") + router.wait_for_file("/run/vpp/cli.sock") + + # make sure VPP initialized correctly + # the sleep is necessary since startupConfig executes *after* the service starts + router.sleep(2) + router.succeed("vppctl show int addr | grep -A1 vlan1 | grep -q fd01::1/64") + router.succeed("vppctl show int addr | grep -A1 vlan2 | grep -q fd02::1/64") + + # wait for server, make sure httpd is reachable + server.wait_for_unit("network.target") + server.wait_for_unit("httpd.service") + server.succeed("curl --fail http://[::1]") + + # wait for client, make sure it can connect to the server through the router + client.wait_for_unit("network.target") + client.succeed("curl --fail http://[fd02::2]") + + # test ICMP + server.succeed("ping -c 1 fd01::2") + client.succeed("ping -c 1 fd02::2") + + # disable interfaces in VPP, make sure server isn't reachable + router.succeed("vppctl set int state vlan1 down") + router.succeed("vppctl set int state vlan2 down") + client.fail("curl --fail --connect-timeout 5 http://[fd02::2]") + client.fail("ping -c 1 fd02::2") + + # restart VPP, make sure it restores its config & server becomes reachable again + router.succeed("systemctl restart vpp-main") + router.wait_for_unit("vpp-main.service") + client.succeed("curl --fail http://[fd02::2]") + client.succeed("ping -c 1 fd02::2") + ''; + } +) diff --git a/pkgs/by-name/vp/vpp/package.nix b/pkgs/by-name/vp/vpp/package.nix index fafcb1784bc95..8a352e234cdad 100644 --- a/pkgs/by-name/vp/vpp/package.nix +++ b/pkgs/by-name/vp/vpp/package.nix @@ -3,6 +3,7 @@ stdenv, fetchFromGitHub, nix-update-script, + nixosTests, cmake, pkg-config, check, @@ -115,6 +116,10 @@ stdenv.mkDerivation rec { passthru.updateScript = nix-update-script { }; + passthru.tests = { + inherit (nixosTests) vpp; + }; + meta = { description = "Fast, scalable layer 2-4 multi-platform network stack running in user space"; homepage = "https://s3-docs.fd.io/vpp/${version}/";