From 921ef37bb04ec62cec9f7be3c5dacf1fb9c37de8 Mon Sep 17 00:00:00 2001 From: Ihar Hrachyshka Date: Tue, 1 Sep 2026 21:33:09 -0400 Subject: [PATCH 1/4] openvswitch: 3.7.1 -> 4.0.0 Announcement: mail.openvswitch.org/pipermail/ovs-announce/2026-August/000400.html NEWS: https://github.com/openvswitch/ovs/blob/main/NEWS This release dropped a few obsolete tools. Upstream systemd units got a few adjustments around dependencies, as well as a socket activation for ovsdb-server. These changes are ported to NixOS module in a later commit: we don't ship upstream units in the package. --- pkgs/by-name/op/openvswitch/package.nix | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/pkgs/by-name/op/openvswitch/package.nix b/pkgs/by-name/op/openvswitch/package.nix index 74222ad18979..f861eb823737 100644 --- a/pkgs/by-name/op/openvswitch/package.nix +++ b/pkgs/by-name/op/openvswitch/package.nix @@ -30,13 +30,13 @@ stdenv.mkDerivation (finalAttrs: { pname = if withDPDK then "openvswitch-dpdk" else "openvswitch"; - version = "3.7.1"; + version = "4.0.0"; src = fetchFromGitHub { owner = "openvswitch"; repo = "ovs"; tag = "v${finalAttrs.version}"; - hash = "sha256-3FQjV4BZZpn7Loiu9Xm30cCqzkU1HgJ3sAc+I6D8OvQ="; + hash = "sha256-+WjpNJkM3AztBY1gPO6RdujGi86GDTjskJyDK16/9Dc="; }; outputs = [ @@ -108,13 +108,9 @@ stdenv.mkDerivation (finalAttrs: { installShellCompletion utilities/ovs-vsctl-bashcomp.bash mkdir -p $tools/{bin,share/openvswitch/scripts} - mv $out/share/openvswitch/bugtool-plugins $tools/share/openvswitch - mv $out/share/openvswitch/scripts/ovs-{bugtool*,check-dead-ifs,monitor-ipsec,vtep} $tools/share/openvswitch/scripts + mv $out/share/openvswitch/scripts/ovs-{check-dead-ifs,monitor-ipsec,vtep} $tools/share/openvswitch/scripts mv $out/share/openvswitch/scripts/usdt $tools/share/openvswitch/scripts - mv $out/bin/ovs-{bugtool,dpctl-top,l3ping,parse-backtrace,pcap,tcpdump,tcpundump,test,vlan-test} $tools/bin - - wrapProgram $tools/bin/ovs-l3ping \ - --prefix PYTHONPATH : $out/share/openvswitch/python + mv $out/bin/ovs-{dpctl-top,pcap,tcpdump,tcpundump} $tools/bin wrapProgram $tools/bin/ovs-tcpdump \ --prefix PATH : ${lib.makeBinPath [ tcpdump ]} \ From f33942b1d1e36682ec4718f18f1625998fc6ee0d Mon Sep 17 00:00:00 2001 From: Ihar Hrachyshka Date: Tue, 1 Sep 2026 21:44:50 -0400 Subject: [PATCH 2/4] openvswitch: enable pytest tests They require all libraries being present, not just pytest runner. --- pkgs/by-name/op/openvswitch/package.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/by-name/op/openvswitch/package.nix b/pkgs/by-name/op/openvswitch/package.nix index f861eb823737..6cfc52b4366b 100644 --- a/pkgs/by-name/op/openvswitch/package.nix +++ b/pkgs/by-name/op/openvswitch/package.nix @@ -134,7 +134,10 @@ stdenv.mkDerivation (finalAttrs: { pyparsing pytest setuptools - ]); + tftpy + ]) + # pyftpdlib depends on pysendfile extension, which cannot be static + ++ lib.optionals (!stdenv.hostPlatform.isStatic) [ python3.pkgs.pyftpdlib ]; passthru = { tests = { From 00fc29ec122eb43e41de0f1c232f17d9e966b35f Mon Sep 17 00:00:00 2001 From: Ihar Hrachyshka Date: Tue, 1 Sep 2026 23:00:46 -0400 Subject: [PATCH 3/4] nixos/openvswitch: use RestartMode=direct Upstream enabled it for its units to avoid cascade failures. https://github.com/openvswitch/ovs/commit/e80b5d3a4375b9cb7e74bcac5aab0d07274e5078 --- nixos/modules/virtualisation/openvswitch.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nixos/modules/virtualisation/openvswitch.nix b/nixos/modules/virtualisation/openvswitch.nix index 4e75d1677955..2f2b4f4ab96d 100644 --- a/nixos/modules/virtualisation/openvswitch.nix +++ b/nixos/modules/virtualisation/openvswitch.nix @@ -105,6 +105,7 @@ in /var/db/openvswitch/conf.db ''; Restart = "always"; + RestartMode = "direct"; RestartSec = 3; PIDFile = "/run/openvswitch/ovsdb.pid"; # Use service type 'forking' to correctly determine when ovsdb-server is ready. @@ -131,6 +132,7 @@ in # Use service type 'forking' to correctly determine when vswitchd is ready. Type = "forking"; Restart = "always"; + RestartMode = "direct"; RestartSec = 3; }; }; From 3234e13977e514efadb9a10e12caaa7abc968db5 Mon Sep 17 00:00:00 2001 From: Ihar Hrachyshka Date: Tue, 1 Sep 2026 23:01:55 -0400 Subject: [PATCH 4/4] nixos/openvswitch: use socket activation for ovsdb It allows vswitchd - and its in-memory state - to survive ovsdb-server restart. (Proved with a NixOS test and a canary openflow rule.) This was implemented in upstream systemd unit files in 4.0.0: https://www.mail-archive.com/ovs-dev%40openvswitch.org/msg102638.html pfd implementation: https://github.com/openvswitch/ovs/commit/aea0116 Assisted-by: Codex, gpt-5.6-sol medium --- nixos/modules/virtualisation/openvswitch.nix | 19 ++++++++++++++--- nixos/tests/openvswitch.nix | 22 ++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/nixos/modules/virtualisation/openvswitch.nix b/nixos/modules/virtualisation/openvswitch.nix index 2f2b4f4ab96d..085de6b61c7f 100644 --- a/nixos/modules/virtualisation/openvswitch.nix +++ b/nixos/modules/virtualisation/openvswitch.nix @@ -64,9 +64,22 @@ in boot.extraModulePackages = [ cfg.package ]; + systemd.sockets.ovsdb = { + description = "Open_vSwitch Database Socket"; + wantedBy = [ "sockets.target" ]; + before = [ "ovsdb.service" ]; + socketConfig = { + ListenStream = "${runDir}/db.sock"; + Service = "ovsdb.service"; + SocketMode = "0770"; + }; + }; + systemd.services.ovsdb = { description = "Open_vSwitch Database Server"; wantedBy = [ "multi-user.target" ]; + requires = [ "ovsdb.socket" ]; + after = [ "ovsdb.socket" ]; path = [ cfg.package ]; restartTriggers = [ db @@ -95,7 +108,7 @@ in serviceConfig = { ExecStart = '' ${cfg.package}/bin/ovsdb-server \ - --remote=punix:${runDir}/db.sock \ + --remote=pfd:3 \ --private-key=db:Open_vSwitch,SSL,private_key \ --certificate=db:Open_vSwitch,SSL,certificate \ --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert \ @@ -119,8 +132,8 @@ in systemd.services.ovs-vswitchd = { description = "Open_vSwitch Daemon"; wantedBy = [ "multi-user.target" ]; - bindsTo = [ "ovsdb.service" ]; - after = [ "ovsdb.service" ]; + requires = [ "ovsdb.socket" ]; + after = [ "ovsdb.socket" ]; path = [ cfg.package ]; serviceConfig = { ExecStart = '' diff --git a/nixos/tests/openvswitch.nix b/nixos/tests/openvswitch.nix index cd725ccb4071..a6296c2a36a2 100644 --- a/nixos/tests/openvswitch.nix +++ b/nixos/tests/openvswitch.nix @@ -58,5 +58,27 @@ node1.wait_until_succeeds("ping -c1 10.0.0.2", timeout=30) node2.wait_until_succeeds("ping -c1 10.0.0.1", timeout=30) + + with subtest("Restarting ovsdb preserves OpenFlow flows"): + ovs_ofctl = "ovs-ofctl -O OpenFlow13" + marker_cookie = "0x5eed" + + def check_marker_flow(): + node1.succeed( + f"{ovs_ofctl} dump-flows vs0 | grep -q 'cookie={marker_cookie}'" + ) + + node1.succeed( + f"{ovs_ofctl} add-flow vs0 " + f"'cookie={marker_cookie},priority=100,ip,nw_src=192.0.2.1,actions=drop'" + ) + check_marker_flow() + + node1.succeed("systemctl restart ovsdb.service") + node1.wait_for_unit("ovsdb.service") + node1.wait_for_unit("ovs-vswitchd.service") + node1.wait_for_unit("vs0-netdev.service") + + check_marker_flow() ''; }