get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.1/patches/2229654/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2229654,
    "url": "http://patchwork.ozlabs.org/api/1.1/patches/2229654/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/openvswitch/patch/20260428151926.3798626-2-i.maximets@ovn.org/",
    "project": {
        "id": 47,
        "url": "http://patchwork.ozlabs.org/api/1.1/projects/47/?format=api",
        "name": "Open vSwitch",
        "link_name": "openvswitch",
        "list_id": "ovs-dev.openvswitch.org",
        "list_email": "ovs-dev@openvswitch.org",
        "web_url": "http://openvswitch.org/",
        "scm_url": "git@github.com:openvswitch/ovs.git",
        "webscm_url": "https://github.com/openvswitch/ovs"
    },
    "msgid": "<20260428151926.3798626-2-i.maximets@ovn.org>",
    "date": "2026-04-28T15:19:06",
    "name": "[ovs-dev,1/6] odp-execute: Remove deprecated AVX512-optimized implementation.",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "66a7d3f890428a5380825a48a842f5a857ed9cca",
    "submitter": {
        "id": 76798,
        "url": "http://patchwork.ozlabs.org/api/1.1/people/76798/?format=api",
        "name": "Ilya Maximets",
        "email": "i.maximets@ovn.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/openvswitch/patch/20260428151926.3798626-2-i.maximets@ovn.org/mbox/",
    "series": [
        {
            "id": 501877,
            "url": "http://patchwork.ozlabs.org/api/1.1/series/501877/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/openvswitch/list/?series=501877",
            "date": "2026-04-28T15:19:05",
            "name": "dpif-netdev: Remove deprecated AVX512-based optimizations.",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/501877/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2229654/comments/",
    "check": "success",
    "checks": "http://patchwork.ozlabs.org/api/patches/2229654/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<ovs-dev-bounces@openvswitch.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "ovs-dev@openvswitch.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@legolas.ozlabs.org",
            "ovs-dev@lists.linuxfoundation.org"
        ],
        "Authentication-Results": [
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)",
            "smtp1.osuosl.org;\n dmarc=none (p=none dis=none) header.from=ovn.org"
        ],
        "Received": [
            "from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g4kd25RmWz1xvV\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 29 Apr 2026 01:19:50 +1000 (AEST)",
            "from localhost (localhost [127.0.0.1])\n\tby smtp4.osuosl.org (Postfix) with ESMTP id E65D041301;\n\tTue, 28 Apr 2026 15:19:48 +0000 (UTC)",
            "from smtp4.osuosl.org ([127.0.0.1])\n by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id L6zmL85_JFaC; Tue, 28 Apr 2026 15:19:45 +0000 (UTC)",
            "from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])\n\tby smtp4.osuosl.org (Postfix) with ESMTPS id B5F6D41328;\n\tTue, 28 Apr 2026 15:19:45 +0000 (UTC)",
            "from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id 9D1F2C04FB;\n\tTue, 28 Apr 2026 15:19:45 +0000 (UTC)",
            "from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 32A00C04FB\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 15:19:45 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n by smtp1.osuosl.org (Postfix) with ESMTP id 4506F83C00\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 15:19:44 +0000 (UTC)",
            "from smtp1.osuosl.org ([127.0.0.1])\n by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id GRkV7G_wOKy3 for <ovs-dev@openvswitch.org>;\n Tue, 28 Apr 2026 15:19:42 +0000 (UTC)",
            "from mail-wr1-f65.google.com (mail-wr1-f65.google.com\n [209.85.221.65])\n by smtp1.osuosl.org (Postfix) with ESMTPS id 4796182283\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 15:19:41 +0000 (UTC)",
            "by mail-wr1-f65.google.com with SMTP id\n ffacd0b85a97d-44509921fbcso1482187f8f.3\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 08:19:41 -0700 (PDT)",
            "from im-t490s.redhat.com (89-24-34-32.nat.epc.tmcz.cz.\n [89.24.34.32])\n by smtp.gmail.com with ESMTPSA id\n ffacd0b85a97d-4463fa89038sm7080967f8f.26.2026.04.28.08.19.37\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 28 Apr 2026 08:19:37 -0700 (PDT)"
        ],
        "X-Virus-Scanned": [
            "amavis at osuosl.org",
            "amavis at osuosl.org"
        ],
        "X-Comment": "SPF check N/A for local connections - client-ip=140.211.9.56;\n helo=lists.linuxfoundation.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN> ",
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 smtp4.osuosl.org B5F6D41328",
            "OpenDKIM Filter v2.11.0 smtp1.osuosl.org 4796182283"
        ],
        "Received-SPF": "Pass (mailfrom) identity=mailfrom; client-ip=209.85.221.65;\n helo=mail-wr1-f65.google.com; envelope-from=i.maximets.ovn@gmail.com;\n receiver=<UNKNOWN>",
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 smtp1.osuosl.org 4796182283",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777389579; x=1777994379;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=4tSEtztfhD0yr8oltTnlWyXlvNuDaiW7c907FVuVMi8=;\n b=ZqBmvoBJWWZwoIp3ru4bLilXeqVYy9BTJKbiKw75IAljOXaR1r4OSO16lX6Is5Sy/p\n n4V4mYw3kmIMPsWCBcjKCwVL7USF8MyLF8bPmFyYoulQjFLw5Ot3cG0yZX/bF8KuCixg\n lq8q9KAn88k34ekcXy6HNkvMVaxFGrVFkMkW0VH4hw3xDstwEds3J52BCkStr44f/wM5\n nuOa+FDZCA1KgvnVutpfQ8UlmuumZGpN8ZsNaB0XaOj/pXsLzUwLIIsf8cKlXm89oday\n IVGgGtUuLjlnDyA/Z4nnFoSZ8w+3QVFzXopPUPa8mhSA3jyAhC15/t5SmjJP39SRzTKt\n T9XQ==",
        "X-Gm-Message-State": "AOJu0YyGbSubP0neOkHPi9d5QroBKGK2F4xvlSYwe2N60NwxGjOt1rGG\n RWmpe5hSR8cduqmuDkBFxkbLQ0tFW3CU9T2Wg8dCQtPL6OZyaV98oR24PjsEfGdOg2c=",
        "X-Gm-Gg": "AeBDiesQ+aG5eI0fOsxabnbSLcxH0IsYK5h4P219mECeQkbge7oyQDisAwN4Bu/yhy6\n yz3zynAdyQFF0Cg2vWKbnh7s2eEiyPdGdP5uhe6tmZryyP0lcvwNxjGxbUua3kq5SsdCo5iONQM\n xWV2UgVStrKiStiWuRS+E6VFX8Y5kSKWvr2XXMUw9y4ewGoGAx5GTClaxkozQFyGoHgPVDOnXnF\n QgSuIpUED8Zg0sbG2AIcL5nBofISrGtEq3XvuX70zBf3XeBjFaHW7w5knY1dOymXYxTiumN2NIP\n HvReLy43MPGs7lI8Ntlr1zmdI13+jHckRctZPCCJjCUtIy5s92EI5D9ky4xQFN18qSgO4nbQbLi\n NihNQNjagjKePfsR5uZS6GjFdJLvIF1Y//Jaj4at7BJGJiyrShb8uwgS/zEItl4fmu0z4euQa33\n zIc+Ij0t8Cexow587XKtMAQWgTP4qsSFiB4HZ+cn/j2TgMriAty8o4FCzvNTsExhrIifE=",
        "X-Received": "by 2002:a05:6000:24c9:b0:43d:71f4:7ed4 with SMTP id\n ffacd0b85a97d-44647dcf634mr6263390f8f.15.1777389578075;\n Tue, 28 Apr 2026 08:19:38 -0700 (PDT)",
        "From": "Ilya Maximets <i.maximets@ovn.org>",
        "To": "ovs-dev@openvswitch.org",
        "Cc": "Ilya Maximets <i.maximets@ovn.org>",
        "Date": "Tue, 28 Apr 2026 17:19:06 +0200",
        "Message-ID": "<20260428151926.3798626-2-i.maximets@ovn.org>",
        "X-Mailer": "git-send-email 2.53.0",
        "In-Reply-To": "<20260428151926.3798626-1-i.maximets@ovn.org>",
        "References": "<20260428151926.3798626-1-i.maximets@ovn.org>",
        "MIME-Version": "1.0",
        "Subject": "[ovs-dev] [PATCH 1/6] odp-execute: Remove deprecated\n AVX512-optimized implementation.",
        "X-BeenThere": "ovs-dev@openvswitch.org",
        "X-Mailman-Version": "2.1.30",
        "Precedence": "list",
        "List-Id": "<ovs-dev.openvswitch.org>",
        "List-Unsubscribe": "<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=unsubscribe>",
        "List-Archive": "<http://mail.openvswitch.org/pipermail/ovs-dev/>",
        "List-Post": "<mailto:ovs-dev@openvswitch.org>",
        "List-Help": "<mailto:ovs-dev-request@openvswitch.org?subject=help>",
        "List-Subscribe": "<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=subscribe>",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "Errors-To": "ovs-dev-bounces@openvswitch.org",
        "Sender": "\"dev\" <ovs-dev-bounces@openvswitch.org>"
    },
    "content": "This functionality was deprecated in 3.7 due to lack of use, testing\nand maintenance.  It's time to remove it.\n\nSigned-off-by: Ilya Maximets <i.maximets@ovn.org>\n---\n Documentation/topics/dpdk/bridge.rst |  35 --\n Documentation/topics/testing.rst     |  24 +-\n NEWS                                 |   2 +\n acinclude.m4                         |  23 -\n configure.ac                         |   1 -\n lib/automake.mk                      |   7 -\n lib/odp-execute-avx512.c             | 813 ---------------------------\n lib/odp-execute-private.c            | 294 ----------\n lib/odp-execute-private.h            | 103 ----\n lib/odp-execute-unixctl.man          |  10 -\n lib/odp-execute.c                    | 167 +-----\n lib/odp-execute.h                    |   9 -\n m4/openvswitch.m4                    |  28 -\n tests/dpif-netdev.at                 |  59 --\n tests/odp.at                         |  39 --\n vswitchd/bridge.c                    |   1 -\n vswitchd/ovs-vswitchd.8.in           |   1 -\n 17 files changed, 29 insertions(+), 1587 deletions(-)\n delete mode 100644 lib/odp-execute-avx512.c\n delete mode 100644 lib/odp-execute-private.c\n delete mode 100644 lib/odp-execute-private.h\n delete mode 100644 lib/odp-execute-unixctl.man",
    "diff": "diff --git a/Documentation/topics/dpdk/bridge.rst b/Documentation/topics/dpdk/bridge.rst\nindex 03c4dd4e3..b4c583df9 100644\n--- a/Documentation/topics/dpdk/bridge.rst\n+++ b/Documentation/topics/dpdk/bridge.rst\n@@ -346,38 +346,3 @@ following command::\n ``scalar`` can be selected on core ``3`` by the following command::\n \n     $ ovs-appctl dpif-netdev/miniflow-parser-set -pmd 3 scalar\n-\n-\n-Actions Implementations (Experimental)\n---------------------------------------\n-\n-.. note::\n-\n-   The AVX512 Actions Implementations feature is deprecated and will be\n-   removed in a future release.\n-\n-Actions describe what processing or modification should be performed on a\n-packet when it matches a given flow. Similar to the datapath interface,\n-DPCLS and MFEX (see above), the implementation of these actions can be\n-accelerated using SIMD instructions, resulting in improved performance.\n-\n-OVS provides multiple implementations of the actions, however some\n-implementations requiring a CPU capable of executing the required SIMD\n-instructions.\n-\n-Available implementations can be listed with the following command::\n-\n-    $ ovs-appctl odp-execute/action-impl-show\n-        Available Actions implementations:\n-            scalar (available: Yes, active: Yes)\n-            autovalidator (available: Yes, active: No)\n-            avx512 (available: Yes, active: No)\n-\n-By default, ``scalar`` is used.  Implementations can be selected by\n-name::\n-\n-    $ ovs-appctl odp-execute/action-impl-set avx512\n-    Action implementation set to avx512.\n-\n-    $ ovs-appctl odp-execute/action-impl-set scalar\n-    Action implementation set to scalar.\ndiff --git a/Documentation/topics/testing.rst b/Documentation/topics/testing.rst\nindex abe670b8b..9531e1e14 100644\n--- a/Documentation/topics/testing.rst\n+++ b/Documentation/topics/testing.rst\n@@ -333,12 +333,12 @@ Userspace datapath: Testing and Validation of CPU-specific Optimizations\n   The AVX512 CPU-specific optimization features are deprecated and will be\n   removed in a future release.\n \n-As multiple versions of the datapath classifier, packet parsing functions and\n-actions can co-exist, each with different CPU ISA optimizations, it is\n-important to validate that they all give the exact same results.  To easily\n-test all the implementations, an ``autovalidator`` implementation of them\n-exists. This implementation runs all other available implementations, and\n-verifies that the results are identical.\n+As multiple versions of the datapath classifier, packet parsing functions\n+can co-exist, each with different CPU ISA optimizations, it is important to\n+validate that they all give the exact same results.  To easily test all the\n+implementations, an ``autovalidator`` implementation of them exists.  This\n+implementation runs all other available implementations, and verifies that\n+the results are identical.\n \n Running the OVS unit tests with the autovalidator enabled ensures all\n implementations provide the same results.  Note that the performance of the\n@@ -354,26 +354,18 @@ To set the autovalidator for the packet parser, use this command::\n \n     $ ovs-appctl dpif-netdev/miniflow-parser-set autovalidator\n \n-To set the autovalidator for actions, use this command::\n-\n-    $ ovs-appctl odp-execute/action-impl-set autovalidator\n-\n To run the OVS unit test suite with the autovalidator as the default\n implementation, it is required to recompile OVS.  During the recompilation,\n the default priority of the `autovalidator` implementation is set to the\n-maximum priority, ensuring every test will be run with every implementation.\n-Priority is only related to mfex autovalidator and not the actions\n-autovalidator.::\n+maximum priority, ensuring every test will be run with every implementation::\n \n-    $ ./configure --enable-autovalidator --enable-mfex-default-autovalidator \\\n-        --enable-actions-default-autovalidator\n+    $ ./configure --enable-autovalidator --enable-mfex-default-autovalidator\n \n The following line should be seen in the configuration log when the above\n options are used::\n \n     checking whether DPCLS Autovalidator is default implementation... yes\n     checking whether MFEX Autovalidator is default implementation... yes\n-    checking whether actions Autovalidator is default implementation... yes\n \n Compile OVS in debug mode to have `ovs_assert` statements error out if\n there is a mismatch in the datapath classifier lookup or packet parser\ndiff --git a/NEWS b/NEWS\nindex 1a3044cbf..f1c5ba871 100644\n--- a/NEWS\n+++ b/NEWS\n@@ -3,6 +3,8 @@ Post-v3.7.0\n    - Userspace datapath:\n      * ARP/ND lookups for native tunnel are now rate limited. The holdout\n        timer can be configured with 'tnl/neigh/retrans_time'.\n+   - The following deprecated AVX512-specific features are now removed:\n+     * AVX512-optimized action handling.\n \n \n v3.7.0 - 16 Feb 2026\ndiff --git a/acinclude.m4 b/acinclude.m4\nindex 060c416f8..8dda44262 100644\n--- a/acinclude.m4\n+++ b/acinclude.m4\n@@ -14,28 +14,6 @@\n # See the License for the specific language governing permissions and\n # limitations under the License.\n \n-dnl Set OVS Actions Autovalidator as the default action implementation\n-dnl at compile time. This enables automatically running all unit tests\n-dnl with all actions implementations.\n-AC_DEFUN([OVS_CHECK_ACTIONS_AUTOVALIDATOR], [\n-  AC_ARG_ENABLE([actions-default-autovalidator],\n-                [AS_HELP_STRING([--enable-actions-default-autovalidator],\n-                                [Enable actions autovalidator as default\n-                                 ovs actions implementation.])],\n-                [autovalidator=yes],[autovalidator=no])\n-  AC_MSG_CHECKING([whether actions Autovalidator is default implementation])\n-  if test \"$autovalidator\" != yes; then\n-    AC_MSG_RESULT([no])\n-  else\n-    AC_DEFINE([ACTIONS_AUTOVALIDATOR_DEFAULT], [1],\n-              [Autovalidator for actions is a default implementation.])\n-    AC_MSG_RESULT([yes])\n-    AC_MSG_WARN(\n-      [Explicit AVX512 feature support will be deprecated in the next release.])\n-  fi\n-])\n-\n-\n dnl Set OVS MFEX Autovalidator as default miniflow extract at compile time?\n dnl This enables automatically running all unit tests with all MFEX\n dnl implementations.\n@@ -104,7 +82,6 @@ dnl\n dnl Checks if compiler and binutils supports various AVX512 ISA.\n AC_DEFUN([OVS_CHECK_AVX512], [\n   OVS_CHECK_BINUTILS_AVX512\n-  OVS_CHECK_GCC_AVX512VL\n   OVS_CONDITIONAL_CC_OPTION_DEFINE([-mavx512f], [HAVE_AVX512F])\n   OVS_CONDITIONAL_CC_OPTION_DEFINE([-mavx512bw], [HAVE_AVX512BW])\n   OVS_CONDITIONAL_CC_OPTION_DEFINE([-mavx512vl], [HAVE_AVX512VL])\ndiff --git a/configure.ac b/configure.ac\nindex 56eacbbc7..0bc6f31ed 100644\n--- a/configure.ac\n+++ b/configure.ac\n@@ -190,7 +190,6 @@ OVS_CONDITIONAL_CC_OPTION([-Wno-unused-parameter], [HAVE_WNO_UNUSED_PARAMETER])\n OVS_ENABLE_WERROR_TOP\n OVS_ENABLE_SPARSE\n OVS_CTAGS_IDENTIFIERS\n-OVS_CHECK_ACTIONS_AUTOVALIDATOR\n OVS_CHECK_DPCLS_AUTOVALIDATOR\n OVS_CHECK_DPIF_AVX512_DEFAULT\n OVS_CHECK_MFEX_AUTOVALIDATOR\ndiff --git a/lib/automake.mk b/lib/automake.mk\nindex c6e988906..f07265261 100644\n--- a/lib/automake.mk\n+++ b/lib/automake.mk\n@@ -44,10 +44,6 @@ lib_libopenvswitchavx512_la_CFLAGS += \\\n lib_libopenvswitchavx512_la_SOURCES += \\\n \tlib/dpif-netdev-extract-avx512.c \\\n \tlib/dpif-netdev-lookup-avx512-gather.c\n-if HAVE_GCC_AVX512VL_GOOD\n-lib_libopenvswitchavx512_la_SOURCES += \\\n-\tlib/odp-execute-avx512.c\n-endif # HAVE_GCC_AVX512VL_GOOD\n endif # HAVE_AVX512VL\n endif # HAVE_AVX512BW\n lib_libopenvswitchavx512_la_LDFLAGS = \\\n@@ -226,8 +222,6 @@ lib_libopenvswitch_la_SOURCES = \\\n \tlib/object-collection.h \\\n \tlib/odp-execute.c \\\n \tlib/odp-execute.h \\\n-\tlib/odp-execute-private.c \\\n-\tlib/odp-execute-private.h \\\n \tlib/odp-util.c \\\n \tlib/odp-util.h \\\n \tlib/ofp-actions.c \\\n@@ -601,7 +595,6 @@ MAN_FRAGMENTS += \\\n \tlib/netdev-dpdk-unixctl.man \\\n \tlib/dpif-netdev-unixctl.man \\\n \tlib/dpif-netlink-unixctl.man \\\n-\tlib/odp-execute-unixctl.man \\\n \tlib/ofp-version.man \\\n \tlib/ovs.tmac \\\n \tlib/ovs-replay.man \\\ndiff --git a/lib/odp-execute-avx512.c b/lib/odp-execute-avx512.c\ndeleted file mode 100644\nindex 55af58737..000000000\n--- a/lib/odp-execute-avx512.c\n+++ /dev/null\n@@ -1,813 +0,0 @@\n-/*\n- * Copyright (c) 2022 Intel.\n- *\n- * Licensed under the Apache License, Version 2.0 (the \"License\");\n- * you may not use this file except in compliance with the License.\n- * You may obtain a copy of the License at:\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-\n-#ifdef __x86_64__\n-/* Sparse cannot handle the AVX512 instructions. */\n-#if !defined(__CHECKER__)\n-\n-#include <config.h>\n-#include <errno.h>\n-#include <sys/types.h>\n-#include <netinet/in.h>\n-#include <netinet/ip6.h>\n-\n-#include \"csum.h\"\n-#include \"dp-packet.h\"\n-#include \"immintrin.h\"\n-#include \"odp-execute.h\"\n-#include \"odp-execute-private.h\"\n-#include \"odp-netlink.h\"\n-#include \"openvswitch/vlog.h\"\n-#include \"packets.h\"\n-\n-VLOG_DEFINE_THIS_MODULE(odp_execute_avx512);\n-\n-/* The below build asserts make sure that the below fields remain in the same\n- * order and offset to l2_pad_size. This is needed as the\n- * avx512_dp_packet_resize_l2() function will manipulate those fields at a\n- * fixed memory index based on the l2_pad_size offset. */\n-BUILD_ASSERT_DECL(offsetof(struct dp_packet, l2_pad_size) +\n-                  MEMBER_SIZEOF(struct dp_packet, l2_pad_size) ==\n-                  offsetof(struct dp_packet, l2_5_ofs));\n-\n-BUILD_ASSERT_DECL(offsetof(struct dp_packet, l2_5_ofs) +\n-                  MEMBER_SIZEOF(struct dp_packet, l2_5_ofs) ==\n-                  offsetof(struct dp_packet, l3_ofs));\n-\n-BUILD_ASSERT_DECL(offsetof(struct dp_packet, l3_ofs) +\n-                           MEMBER_SIZEOF(struct dp_packet, l3_ofs) ==\n-                           offsetof(struct dp_packet, l4_ofs));\n-\n-BUILD_ASSERT_DECL(offsetof(struct dp_packet, l4_ofs) +\n-                           MEMBER_SIZEOF(struct dp_packet, l4_ofs) ==\n-                           offsetof(struct dp_packet, inner_l3_ofs));\n-\n-BUILD_ASSERT_DECL(offsetof(struct dp_packet, inner_l3_ofs) +\n-                           MEMBER_SIZEOF(struct dp_packet, inner_l3_ofs) ==\n-                           offsetof(struct dp_packet, inner_l4_ofs));\n-\n-/* The below build assert makes sure it's safe to read/write 128-bits starting\n- * at the l2_pad_size location. */\n-BUILD_ASSERT_DECL(sizeof(struct dp_packet) -\n-                  offsetof(struct dp_packet, l2_pad_size) >= sizeof(__m128i));\n-\n-/* The below build assert makes sure the order of the fields needed by\n- * the set masked functions shuffle operations do not change. This should not\n- * happen as these are defined under the Linux uapi. */\n-BUILD_ASSERT_DECL(offsetof(struct ovs_key_ethernet, eth_src) +\n-                  MEMBER_SIZEOF(struct ovs_key_ethernet, eth_src) ==\n-                  offsetof(struct ovs_key_ethernet, eth_dst));\n-\n-BUILD_ASSERT_DECL(offsetof(struct ovs_key_ipv4, ipv4_src) +\n-                  MEMBER_SIZEOF(struct ovs_key_ipv4, ipv4_src) ==\n-                  offsetof(struct ovs_key_ipv4, ipv4_dst));\n-\n-BUILD_ASSERT_DECL(offsetof(struct ovs_key_ipv4, ipv4_dst) +\n-                  MEMBER_SIZEOF(struct ovs_key_ipv4, ipv4_dst) ==\n-                  offsetof(struct ovs_key_ipv4, ipv4_proto));\n-\n-BUILD_ASSERT_DECL(offsetof(struct ovs_key_ipv4, ipv4_proto) +\n-                  MEMBER_SIZEOF(struct ovs_key_ipv4, ipv4_proto) ==\n-                  offsetof(struct ovs_key_ipv4, ipv4_tos));\n-\n-BUILD_ASSERT_DECL(offsetof(struct ovs_key_ipv4, ipv4_tos) +\n-                  MEMBER_SIZEOF(struct ovs_key_ipv4, ipv4_tos) ==\n-                  offsetof(struct ovs_key_ipv4, ipv4_ttl));\n-\n-BUILD_ASSERT_DECL(offsetof(struct ovs_key_ipv6, ipv6_src) +\n-                  MEMBER_SIZEOF(struct ovs_key_ipv6, ipv6_src) ==\n-                  offsetof(struct ovs_key_ipv6, ipv6_dst));\n-\n-BUILD_ASSERT_DECL(offsetof(struct ovs_key_ipv6, ipv6_dst) +\n-                  MEMBER_SIZEOF(struct ovs_key_ipv6, ipv6_dst) ==\n-                  offsetof(struct ovs_key_ipv6, ipv6_label));\n-\n-BUILD_ASSERT_DECL(offsetof(struct ovs_key_ipv6, ipv6_label) +\n-                  MEMBER_SIZEOF(struct ovs_key_ipv6, ipv6_label) ==\n-                  offsetof(struct ovs_key_ipv6, ipv6_proto));\n-\n-BUILD_ASSERT_DECL(offsetof(struct ovs_key_ipv6, ipv6_proto) +\n-                  MEMBER_SIZEOF(struct ovs_key_ipv6, ipv6_proto) ==\n-                  offsetof(struct ovs_key_ipv6, ipv6_tclass));\n-\n-BUILD_ASSERT_DECL(offsetof(struct ovs_key_ipv6, ipv6_tclass) +\n-                  MEMBER_SIZEOF(struct ovs_key_ipv6, ipv6_tclass) ==\n-                  offsetof(struct ovs_key_ipv6, ipv6_hlimit));\n-\n-/* Array of callback functions, one for each masked operation. */\n-static odp_execute_action_cb impl_set_masked_funcs[__OVS_KEY_ATTR_MAX];\n-\n-static inline void ALWAYS_INLINE\n-avx512_dp_packet_resize_l2(struct dp_packet *b, int resize_by_bytes)\n-{\n-    /* Update packet size/data pointers, same as the scalar implementation. */\n-    if (resize_by_bytes >= 0) {\n-        dp_packet_push_uninit(b, resize_by_bytes);\n-    } else {\n-        dp_packet_pull(b, -resize_by_bytes);\n-    }\n-\n-    /* The next step is to update the l2_5_ofs to inner_l4_ofs fields which\n-     * the scalar implementation does with the  dp_packet_adjust_layer_offset()\n-     * function. */\n-\n-    /* Set the v_zero register to all zero's. */\n-    const __m128i v_zeros = _mm_setzero_si128();\n-\n-    /* Set the v_u16_max register to all one's. */\n-    const __m128i v_u16_max = _mm_cmpeq_epi16(v_zeros, v_zeros);\n-\n-    /* Each lane represents 16 bits in a 128-bit register. Here the bitmask\n-     * starts at l2_5_ofs with a value of 0 indicating it is not modified. Then\n-     * five 1's to indicate modificaiton of all fields from l2_5_ofs to\n-     * inner_l4_ofs. */\n-    const uint8_t k_lanes = 0b111110;\n-\n-    /* Set all 16-bit words in the 128-bits v_offset register to the value we\n-     * need to add/substract from the l2_5_ofs to inner_l4_ofs fields. */\n-    __m128i v_offset = _mm_set1_epi16(abs(resize_by_bytes));\n-\n-    /* Load 128 bits from the dp_packet structure starting at the l2_pad_size\n-     * offset. */\n-    void *adjust_ptr = &b->l2_pad_size;\n-    __m128i v_adjust_src = _mm_loadu_si128(adjust_ptr);\n-\n-    /* Here is the tricky part, we only need to update the value of the three\n-     * fields if they are not UINT16_MAX. The following function will return\n-     * a mask of lanes (read fields) that are not UINT16_MAX. It will do this\n-     * by comparing only the lanes we requested, k_lanes, and if they match\n-     * v_u16_max, the bit will be set. */\n-    __mmask8 k_cmp = _mm_mask_cmpneq_epu16_mask(k_lanes, v_adjust_src,\n-                                                v_u16_max);\n-\n-    /* Based on the bytes adjust (positive, or negative) it will do the actual\n-     * add or subtraction. These functions will only operate on the lanes\n-     * (fields) requested based on k_cmp, i.e:\n-     *   k_cmp = [l2_5_ofs, ..., inner_l4_ofs]\n-     *   for field in kcmp\n-     *       v_adjust_src[field] = v_adjust_src[field] + v_offset\n-     */\n-    __m128i v_adjust_wip;\n-\n-    if (resize_by_bytes >= 0) {\n-        v_adjust_wip = _mm_mask_add_epi16(v_adjust_src, k_cmp,\n-                                          v_adjust_src, v_offset);\n-    } else {\n-        v_adjust_wip = _mm_mask_sub_epi16(v_adjust_src, k_cmp,\n-                                          v_adjust_src, v_offset);\n-    }\n-\n-    /* Here we write back the full 128-bits. */\n-    _mm_storeu_si128(adjust_ptr, v_adjust_wip);\n-}\n-\n-/* This function performs the same operation on each packet in the batch as\n- * the scalar eth_pop_vlan() function. */\n-static void\n-action_avx512_pop_vlan(struct dp_packet_batch *batch,\n-                       const struct nlattr *a OVS_UNUSED)\n-{\n-    struct dp_packet *packet;\n-\n-    /* Set the v_zero register to all zero's. */\n-    const __m128i v_zeros = _mm_setzero_si128();\n-\n-    DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {\n-        struct vlan_eth_header *veh = dp_packet_eth(packet);\n-\n-        if (veh && dp_packet_size(packet) >= sizeof *veh &&\n-            eth_type_vlan(veh->veth_type)) {\n-\n-            /* Load the first 128-bits of l2 header into the v_ether register.\n-             * This result in the veth_dst/src and veth_type/tci of the\n-             * vlan_eth_header structure to be loaded. */\n-            __m128i v_ether = _mm_loadu_si128((void *) veh);\n-\n-            /* This creates a 256-bit value containing the first four fields\n-             * of the vlan_eth_header plus 128 zero-bit. The result will be the\n-             * lowest 128-bits after the right shift, hence we shift the data\n-             * 128(zero)-bits minus the VLAN_HEADER_LEN, so we are left with\n-             * only the veth_dst and veth_src fields. */\n-            __m128i v_realign = _mm_alignr_epi8(v_ether, v_zeros,\n-                                                sizeof(__m128i) -\n-                                                VLAN_HEADER_LEN);\n-\n-            /* Write back the modified ethernet header. */\n-            _mm_storeu_si128((void *) veh, v_realign);\n-\n-            /* As we removed the VLAN_HEADER we now need to adjust all the\n-             * offsets. */\n-            avx512_dp_packet_resize_l2(packet, -VLAN_HEADER_LEN);\n-        }\n-    }\n-}\n-\n-/* This function performs the same operation on each packet in the batch as\n- * the scalar eth_push_vlan() function. */\n-static void\n-action_avx512_push_vlan(struct dp_packet_batch *batch, const struct nlattr *a)\n-{\n-    struct dp_packet *packet;\n-    const struct ovs_action_push_vlan *vlan = nl_attr_get(a);\n-    ovs_be16 tpid, tci;\n-\n-    /* This shuffle mask is used below, and each position tells where to\n-     * move the bytes to. So here, the fourth byte in v_ether is moved to\n-     * byte location 0 in v_shift. The fifth is moved to 1, etc., etc.\n-     * The 0xFF is special it tells to fill that position with 0. */\n-    static const uint8_t vlan_push_shuffle_mask[16] = {\n-        4, 5, 6, 7, 8, 9, 10, 11,\n-        12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF\n-    };\n-\n-    /* Load the shuffle mask in v_index. */\n-    __m128i v_index = _mm_loadu_si128((void *) vlan_push_shuffle_mask);\n-\n-    DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {\n-        tpid = vlan->vlan_tpid;\n-        tci = vlan->vlan_tci;\n-\n-        /* As we are about to insert the VLAN_HEADER we now need to adjust all\n-         * the offsets. */\n-        avx512_dp_packet_resize_l2(packet, VLAN_HEADER_LEN);\n-\n-        char *pkt_data = (char *) dp_packet_data(packet);\n-\n-        /* Build up the VLAN TCI/TPID in a single uint32_t. */\n-        const uint32_t tci_proc = tci & htons(~VLAN_CFI);\n-        const uint32_t tpid_tci = (tci_proc << 16) | tpid;\n-\n-        /* Load the first 128-bits of the packet into the v_ether register.\n-         * Note that this includes the 4 unused bytes (VLAN_HEADER_LEN). */\n-        __m128i v_ether = _mm_loadu_si128((void *) pkt_data);\n-\n-        /* Move(shuffle) the veth_dst and veth_src data to create room for\n-         * the vlan header. */\n-        __m128i v_shift = _mm_shuffle_epi8(v_ether, v_index);\n-\n-        /* Copy(insert) the 32-bit VLAN header, tpid_tci, at the 3rd 32-bit\n-         * word offset, i.e. ofssetof(vlan_eth_header, veth_type) */\n-        __m128i v_vlan_hdr = _mm_insert_epi32(v_shift, tpid_tci, 3);\n-\n-        /* Write back the modified ethernet header. */\n-        _mm_storeu_si128((void *) pkt_data, v_vlan_hdr);\n-    }\n-}\n-\n-/* This function performs the same operation on each packet in the batch as\n- * the scalar odp_eth_set_addrs() function. */\n-static void\n-action_avx512_eth_set_addrs(struct dp_packet_batch *batch,\n-                            const struct nlattr *a)\n-{\n-    const struct ovs_key_ethernet *key, *mask;\n-    struct dp_packet *packet;\n-\n-    a = nl_attr_get(a);\n-    key = nl_attr_get(a);\n-    mask = odp_get_key_mask(a, struct ovs_key_ethernet);\n-\n-    /* Read the content of the key(src) and mask in the respective registers.\n-     * We only load the src and dest addresses, which is only 96-bits and not\n-     * 128-bits. */\n-    __m128i v_src = _mm_maskz_loadu_epi32(0x7,(void *) key);\n-    __m128i v_mask = _mm_maskz_loadu_epi32(0x7, (void *) mask);\n-\n-\n-    /* These shuffle masks are used below, and each position tells where to\n-     * move the bytes to. So here, the fourth sixth byte in\n-     * ovs_key_ethernet is moved to byte location 0 in v_src/v_mask.\n-     * The seventh is moved to 1, etc., etc.\n-     * This swap is needed to move the src and dest MAC addresses in the\n-     * same order as in the ethernet packet. */\n-    static const uint8_t eth_shuffle[16] = {\n-        6, 7, 8, 9, 10, 11, 0, 1,\n-        2, 3, 4, 5, 0xFF, 0xFF, 0xFF, 0xFF\n-    };\n-\n-    /* Load the shuffle mask in v_shuf. */\n-    __m128i v_shuf = _mm_loadu_si128((void *) eth_shuffle);\n-\n-    /* Swap the key/mask src and dest addresses to the ethernet order. */\n-    v_src = _mm_shuffle_epi8(v_src, v_shuf);\n-    v_mask = _mm_shuffle_epi8(v_mask, v_shuf);\n-\n-    DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {\n-\n-        struct eth_header *eh = dp_packet_eth(packet);\n-\n-        if (!eh) {\n-            continue;\n-        }\n-\n-        /* Load the first 128-bits of the packet into the v_ether register. */\n-        __m128i v_dst = _mm_loadu_si128((void *) eh);\n-\n-        /* AND the v_mask to the packet data (v_dst). */\n-        __m128i dst_masked = _mm_andnot_si128(v_mask, v_dst);\n-\n-        /* OR the new addresses (v_src) with the masked packet addresses\n-         * (dst_masked). */\n-        __m128i res = _mm_or_si128(v_src, dst_masked);\n-\n-        /* Write back the modified ethernet addresses. */\n-        _mm_storeu_si128((void *) eh, res);\n-    }\n-}\n-\n-static inline uint16_t ALWAYS_INLINE\n-avx512_get_delta(__m256i old_header, __m256i new_header)\n-{\n-    __m256i v_zeros = _mm256_setzero_si256();\n-\n-    /* These two shuffle masks, v_swap16a and v_swap16b, are to shuffle the\n-     * old and new header to add padding after each 16-bit value for the\n-     * following carry over addition. */\n-    __m256i v_swap16a = _mm256_setr_epi16(0x0100, 0xFFFF, 0x0302, 0xFFFF,\n-                                          0x0504, 0xFFFF, 0x0706, 0xFFFF,\n-                                          0x0100, 0xFFFF, 0x0302, 0xFFFF,\n-                                          0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);\n-    __m256i v_swap16b = _mm256_setr_epi16(0x0908, 0xFFFF, 0x0B0A, 0xFFFF,\n-                                          0x0D0C, 0xFFFF, 0x0F0E, 0xFFFF,\n-                                          0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,\n-                                          0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);\n-    __m256i v_shuf_old1 = _mm256_shuffle_epi8(old_header, v_swap16a);\n-    __m256i v_shuf_old2 = _mm256_shuffle_epi8(old_header, v_swap16b);\n-    __m256i v_shuf_new1 = _mm256_shuffle_epi8(new_header, v_swap16a);\n-    __m256i v_shuf_new2 = _mm256_shuffle_epi8(new_header, v_swap16b);\n-\n-    /* Add each part of the old and new headers together. */\n-    __m256i v_delta1 = _mm256_add_epi32(v_shuf_old1, v_shuf_new1);\n-    __m256i v_delta2 = _mm256_add_epi32(v_shuf_old2, v_shuf_new2);\n-\n-    /* Add old and new header. */\n-    __m256i v_delta = _mm256_add_epi32(v_delta1, v_delta2);\n-\n-    /* Perform horizontal add to go from 8x32-bits to 2x32-bits. */\n-    v_delta = _mm256_hadd_epi32(v_delta, v_zeros);\n-    v_delta = _mm256_hadd_epi32(v_delta, v_zeros);\n-\n-    /* Shuffle 32-bit value from 3rd lane into first lane for final\n-     * horizontal add. */\n-    __m256i v_swap32a = _mm256_setr_epi32(0x0, 0x4, 0xF, 0xF,\n-                                          0xF, 0xF, 0xF, 0xF);\n-    v_delta = _mm256_permutexvar_epi32(v_swap32a, v_delta);\n-\n-    v_delta = _mm256_hadd_epi32(v_delta, v_zeros);\n-    v_delta = _mm256_shuffle_epi8(v_delta, v_swap16a);\n-    v_delta = _mm256_hadd_epi32(v_delta, v_zeros);\n-    v_delta = _mm256_hadd_epi16(v_delta, v_zeros);\n-\n-    /* Extract delta value. */\n-    return _mm256_extract_epi16(v_delta, 0);\n-}\n-\n-/* This function will calculate the csum delta for the IPv4 addresses in the\n- * new_header and old_header, assuming the csum field on the new_header was\n- * updated. */\n-static inline uint16_t ALWAYS_INLINE\n-avx512_ipv4_addr_csum_delta(__m256i old_header, __m256i new_header)\n-{\n-    __m256i v_zeros = _mm256_setzero_si256();\n-\n-    /* Set the v_ones register to all one's. */\n-    __m256i v_ones = _mm256_cmpeq_epi16(v_zeros, v_zeros);\n-\n-    /* Combine the old and new header, i.e. adding in the new IP addresses\n-     * in the old header (oh). This is done by using the 0x03C 16-bit mask,\n-     * picking 16-bit word 7 till 10.  */\n-    __m256i v_blend_new = _mm256_mask_blend_epi16(0x03C0, old_header,\n-                                                  new_header);\n-\n-    /* Invert the old_header register. */\n-    old_header =_mm256_andnot_si256(old_header, v_ones);\n-\n-    /* Calculate the delta between the old and new header. */\n-    return avx512_get_delta(old_header, v_blend_new);\n-}\n-\n-/* This function will calculate the csum delta between the new_header and\n- * old_header, assuming the csum field on the new_header was not yet updated\n- * or reset. It also assumes headers contain the first 20-bytes of the IPv4\n- * header data, and the rest is zeroed out. */\n-static inline uint16_t ALWAYS_INLINE\n-avx512_ipv4_hdr_csum_delta(__m256i old_header, __m256i new_header)\n-{\n-    __m256i v_zeros = _mm256_setzero_si256();\n-\n-    /* Set the v_ones register to all one's. */\n-    __m256i v_ones = _mm256_cmpeq_epi16(v_zeros, v_zeros);\n-\n-    /* Invert the old_header register. */\n-    old_header =_mm256_andnot_si256(old_header, v_ones);\n-\n-    /* Calculate the delta between the old and new header. */\n-    return avx512_get_delta(old_header, new_header);\n-}\n-\n-/* This function performs the same operation on each packet in the batch as\n- * the scalar odp_set_ipv4() function. */\n-static void\n-action_avx512_ipv4_set_addrs(struct dp_packet_batch *batch,\n-                             const struct nlattr *a)\n-{\n-    const struct ovs_key_ipv4 *key, *mask;\n-    struct dp_packet *packet;\n-    a = nl_attr_get(a);\n-    key = nl_attr_get(a);\n-    mask = odp_get_key_mask(a, struct ovs_key_ipv4);\n-\n-    /* Read the content of the key(src) and mask in the respective registers.\n-     * We only load the size of the actual structure, which is only 96-bits. */\n-    __m256i v_key = _mm256_maskz_loadu_epi32(0x7, (void *) key);\n-    __m256i v_mask = _mm256_maskz_loadu_epi32(0x7, (void *) mask);\n-\n-    /* This two shuffle masks, v_shuf32, v_shuffle, are to shuffle key and\n-     * mask to match the ip_header structure layout. */\n-    static const uint8_t ip_shuffle_mask[32] = {\n-            0xFF, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n-            0x06, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03,\n-            0x00, 0x01, 0x02, 0x03, 0xFF, 0xFF, 0xFF, 0xFF,\n-            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};\n-\n-    __m256i v_shuf32 = _mm256_setr_epi32(0x0, 0x2, 0xF, 0xF,\n-                                         0x1, 0xF, 0xF, 0xF);\n-\n-    __m256i v_shuffle = _mm256_loadu_si256((void *) ip_shuffle_mask);\n-\n-    /* Two shuffles are required for key and mask to match the layout of\n-     * the ip_header struct. The _shuffle_epi8 only works within 128-bit\n-     * lanes, so a permute is required to move src and dst into the correct\n-     * lanes. And then a shuffle is used to move the fields into the right\n-     * order. */\n-    __m256i v_key_shuf = _mm256_permutexvar_epi32(v_shuf32, v_key);\n-    v_key_shuf = _mm256_shuffle_epi8(v_key_shuf, v_shuffle);\n-\n-    __m256i v_mask_shuf = _mm256_permutexvar_epi32(v_shuf32, v_mask);\n-    v_mask_shuf = _mm256_shuffle_epi8(v_mask_shuf, v_shuffle);\n-\n-    DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {\n-        struct ip_header *nh = dp_packet_l3(packet);\n-\n-        /* Load the 20 bytes of the IPv4 header. Without options, which is the\n-         * most common case it's 20 bytes, but can be up to 60 bytes. */\n-        __m256i v_packet = _mm256_maskz_loadu_epi32(0x1F, (void *) nh);\n-\n-        /* AND the v_pkt_mask to the packet data (v_packet). */\n-        __m256i v_pkt_masked = _mm256_andnot_si256(v_mask_shuf, v_packet);\n-\n-        /* OR the new addresses (v_key_shuf) with the masked packet addresses\n-         * (v_pkt_masked). */\n-        __m256i v_new_hdr = _mm256_or_si256(v_key_shuf, v_pkt_masked);\n-\n-        if (dp_packet_ip_checksum_valid(packet)) {\n-            dp_packet_ip_checksum_set_partial(packet);\n-        } else {\n-            ovs_be16 old_csum = ~nh->ip_csum;\n-\n-            /* Update the IP checksum based on updated IP values. */\n-            uint16_t delta = avx512_ipv4_hdr_csum_delta(v_packet, v_new_hdr);\n-            uint32_t new_csum = old_csum + delta;\n-\n-            delta = csum_finish(new_csum);\n-\n-            /* Insert new checksum. */\n-            v_new_hdr = _mm256_insert_epi16(v_new_hdr, delta, 5);\n-        }\n-\n-        /* If ip_src or ip_dst has been modified, L4 checksum needs to\n-         * be updated too. */\n-        if (mask->ipv4_src || mask->ipv4_dst) {\n-\n-            uint16_t delta_checksum = avx512_ipv4_addr_csum_delta(v_packet,\n-                                                                  v_new_hdr);\n-            size_t l4_size = dp_packet_l4_size(packet);\n-\n-            if (nh->ip_proto == IPPROTO_UDP && l4_size >= UDP_HEADER_LEN) {\n-                struct udp_header *uh = dp_packet_l4(packet);\n-                if (dp_packet_l4_checksum_valid(packet)) {\n-                    dp_packet_l4_checksum_set_partial(packet);\n-                } else if (uh->udp_csum) {\n-                    /* New UDP checksum. */\n-                    uint16_t old_udp_checksum = ~uh->udp_csum;\n-                    uint32_t udp_checksum = old_udp_checksum + delta_checksum;\n-                    udp_checksum = csum_finish(udp_checksum);\n-\n-                    if (!udp_checksum) {\n-                        udp_checksum = htons(0xffff);\n-                    }\n-                    /* Insert new udp checksum. */\n-                    uh->udp_csum = udp_checksum;\n-                }\n-            } else if (nh->ip_proto == IPPROTO_TCP &&\n-                       l4_size >= TCP_HEADER_LEN) {\n-                if (dp_packet_l4_checksum_valid(packet)) {\n-                    dp_packet_l4_checksum_set_partial(packet);\n-                } else {\n-                    /* New TCP checksum. */\n-                    struct tcp_header *th = dp_packet_l4(packet);\n-                    uint16_t old_tcp_checksum = ~th->tcp_csum;\n-                    uint32_t tcp_checksum = old_tcp_checksum + delta_checksum;\n-                    tcp_checksum = csum_finish(tcp_checksum);\n-\n-                    th->tcp_csum = tcp_checksum;\n-                }\n-            }\n-\n-            pkt_metadata_init_conn(&packet->md);\n-        }\n-        /* Write back the modified IPv4 addresses. */\n-        _mm256_mask_storeu_epi32((void *) nh, 0x1F, v_new_hdr);\n-    }\n-}\n-\n-#if HAVE_AVX512VBMI\n-static inline uint16_t ALWAYS_INLINE\n-__attribute__((__target__(\"avx512vbmi\")))\n-avx512_ipv6_sum_header(__m512i ip6_header)\n-{\n-    __m256i v_zeros = _mm256_setzero_si256();\n-    __m512i v_shuf_src_dst = _mm512_setr_epi64(0x01, 0x02, 0x03, 0x04,\n-                                               0xFF, 0xFF, 0xFF, 0xFF);\n-\n-    /* Shuffle ip6 src and dst to beginning of register. */\n-    __m512i v_ip6_hdr_shuf = _mm512_permutexvar_epi64(v_shuf_src_dst,\n-                                                      ip6_header);\n-\n-    /* Extract ip6 src and dst into smaller 256-bit wide register. */\n-    __m256i v_ip6_src_dst = _mm512_extracti64x4_epi64(v_ip6_hdr_shuf, 0);\n-\n-    /* These two shuffle masks, v_swap16a and v_swap16b, are to shuffle the\n-     * src and dst fields and add padding after each 16-bit value for the\n-     * following carry over addition. */\n-    __m256i v_swap16a = _mm256_setr_epi16(0x0100, 0xFFFF, 0x0302, 0xFFFF,\n-                                          0x0504, 0xFFFF, 0x0706, 0xFFFF,\n-                                          0x0100, 0xFFFF, 0x0302, 0xFFFF,\n-                                          0x0504, 0xFFFF, 0x0706, 0xFFFF);\n-    __m256i v_swap16b = _mm256_setr_epi16(0x0908, 0xFFFF, 0x0B0A, 0xFFFF,\n-                                          0x0D0C, 0xFFFF, 0x0F0E, 0xFFFF,\n-                                          0x0908, 0xFFFF, 0x0B0A, 0xFFFF,\n-                                          0x0D0C, 0xFFFF, 0x0F0E, 0xFFFF);\n-    __m256i v_shuf_old1 = _mm256_shuffle_epi8(v_ip6_src_dst, v_swap16a);\n-    __m256i v_shuf_old2 = _mm256_shuffle_epi8(v_ip6_src_dst, v_swap16b);\n-\n-    /* Add each part of the old and new headers together. */\n-    __m256i v_delta = _mm256_add_epi32(v_shuf_old1, v_shuf_old2);\n-\n-    /* Perform horizontal add to go from 8x32-bits to 2x32-bits. */\n-    v_delta = _mm256_hadd_epi32(v_delta, v_zeros);\n-    v_delta = _mm256_hadd_epi32(v_delta, v_zeros);\n-\n-    /* Shuffle 32-bit value from 3rd lane into first lane for final\n-     * horizontal add. */\n-    __m256i v_swap32a = _mm256_setr_epi32(0x0, 0x4, 0xF, 0xF,\n-                                          0xF, 0xF, 0xF, 0xF);\n-\n-    v_delta = _mm256_permutexvar_epi32(v_swap32a, v_delta);\n-\n-    v_delta = _mm256_hadd_epi32(v_delta, v_zeros);\n-    v_delta = _mm256_shuffle_epi8(v_delta, v_swap16a);\n-    v_delta = _mm256_hadd_epi32(v_delta, v_zeros);\n-    v_delta = _mm256_hadd_epi16(v_delta, v_zeros);\n-\n-    /* Extract delta value. */\n-    return _mm256_extract_epi16(v_delta, 0);\n-}\n-\n-static inline uint16_t ALWAYS_INLINE\n-__attribute__((__target__(\"avx512vbmi\")))\n-avx512_ipv6_addr_csum_delta(__m512i v_packet, __m512i v_new_hdr,\n-                            bool rh_present)\n-{\n-    __m512i v_new_hdr_for_cksum = v_new_hdr;\n-    uint32_t csum_delta;\n-    uint16_t old_delta;\n-    uint16_t new_delta;\n-\n-    if (rh_present) {\n-        v_new_hdr_for_cksum = _mm512_mask_blend_epi64(0x18, v_new_hdr,\n-                                                      v_packet);\n-    }\n-\n-    old_delta = avx512_ipv6_sum_header(v_packet);\n-    new_delta = avx512_ipv6_sum_header(v_new_hdr_for_cksum);\n-    csum_delta = ((uint16_t) ~old_delta) + new_delta;\n-\n-    return ~csum_finish(csum_delta);\n-}\n-\n-/* This function performs the same operation on each packet in the batch as\n- * the scalar odp_set_ipv6() function. */\n-static void\n-__attribute__((__target__(\"avx512vbmi\")))\n-action_avx512_set_ipv6(struct dp_packet_batch *batch, const struct nlattr *a)\n-{\n-    const struct ovs_key_ipv6 *key, *mask;\n-    struct dp_packet *packet;\n-\n-    a = nl_attr_get(a);\n-    key = nl_attr_get(a);\n-    mask = odp_get_key_mask(a, struct ovs_key_ipv6);\n-\n-    /* Read the content of the key and mask in the respective registers. We\n-     * only load the size of the actual structure, which is only 40 bytes. */\n-    __m512i v_key = _mm512_maskz_loadu_epi64(0x1F, (void *) key);\n-    __m512i v_mask = _mm512_maskz_loadu_epi64(0x1F, (void *) mask);\n-\n-    /* This shuffle mask v_shuffle, is to shuffle key and mask to match the\n-     * ip6_hdr structure layout. */\n-    static const uint8_t ip_shuffle_mask[64] = {\n-        0x20, 0x21, 0x22, 0x23, 0xFF, 0xFF, 0x24, 0x26,\n-        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\n-        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,\n-        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,\n-        0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,\n-        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0XFF, 0xFF, 0xFF,\n-        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n-        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0XFF, 0xFF\n-    };\n-\n-    __m512i v_shuffle = _mm512_loadu_si512((void *) ip_shuffle_mask);\n-\n-    /* This shuffle is required for key and mask to match the layout of the\n-     * ip6_hdr struct. */\n-    __m512i v_key_shuf = _mm512_permutexvar_epi8(v_shuffle, v_key);\n-    __m512i v_mask_shuf = _mm512_permutexvar_epi8(v_shuffle, v_mask);\n-\n-    /* Set the v_zero register to all zero's. */\n-    const __m128i v_zeros = _mm_setzero_si128();\n-\n-    /* Set the v_all_ones register to all one's. */\n-    const __m128i v_all_ones = _mm_cmpeq_epi16(v_zeros, v_zeros);\n-\n-    /* Load ip6 src and dst masks respectively into 128-bit wide registers. */\n-    __m128i v_src = _mm_loadu_si128((void *) &mask->ipv6_src);\n-    __m128i v_dst = _mm_loadu_si128((void *) &mask->ipv6_dst);\n-\n-    /* Perform a bitwise OR between src and dst registers. */\n-    __m128i v_or = _mm_or_si128(v_src, v_dst);\n-\n-    /* Will return true if any bit has been set in v_or, else it will return\n-     * false. */\n-    bool do_checksum = !_mm_test_all_zeros(v_or, v_all_ones);\n-\n-    DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {\n-        struct ovs_16aligned_ip6_hdr *nh = dp_packet_l3(packet);\n-\n-        /* Load the 40 bytes of the IPv6 header. */\n-        __m512i v_packet = _mm512_maskz_loadu_epi64(0x1F, (void *) nh);\n-\n-        /* AND the v_pkt_mask to the packet data (v_packet). */\n-        __m512i v_pkt_masked = _mm512_andnot_si512(v_mask_shuf, v_packet);\n-\n-        /* OR the new addresses (v_key_shuf) with the masked packet addresses\n-         * (v_pkt_masked). */\n-        __m512i v_new_hdr = _mm512_or_si512(v_key_shuf, v_pkt_masked);\n-\n-        /* If ip6_src or ip6_dst has been modified, L4 checksum needs to be\n-         * updated. */\n-        uint8_t proto = 0;\n-        bool rh_present;\n-        bool do_csum = do_checksum;\n-\n-        rh_present = packet_rh_present(packet, &proto, &do_csum);\n-\n-        if (do_csum) {\n-            size_t l4_size = dp_packet_l4_size(packet);\n-            uint16_t delta_checksum;\n-\n-            if (proto == IPPROTO_UDP && l4_size >= UDP_HEADER_LEN) {\n-                struct udp_header *uh = dp_packet_l4(packet);\n-                if (dp_packet_l4_checksum_valid(packet)) {\n-                    dp_packet_l4_checksum_set_partial(packet);\n-                } else if (uh->udp_csum) {\n-                    delta_checksum = avx512_ipv6_addr_csum_delta(v_packet,\n-                                                                 v_new_hdr,\n-                                                                 rh_present);\n-                    uint16_t old_udp_checksum = ~uh->udp_csum;\n-                    uint32_t udp_checksum = old_udp_checksum +\n-                                            delta_checksum;\n-\n-                    udp_checksum = csum_finish(udp_checksum);\n-\n-                    if (!udp_checksum) {\n-                        udp_checksum = htons(0xffff);\n-                    }\n-\n-                    uh->udp_csum = udp_checksum;\n-                }\n-\n-            } else if (proto == IPPROTO_TCP && l4_size >= TCP_HEADER_LEN) {\n-                if (dp_packet_l4_checksum_valid(packet)) {\n-                    dp_packet_l4_checksum_set_partial(packet);\n-                } else {\n-                    delta_checksum = avx512_ipv6_addr_csum_delta(v_packet,\n-                                                                 v_new_hdr,\n-                                                                 rh_present);\n-                    struct tcp_header *th = dp_packet_l4(packet);\n-                    uint16_t old_tcp_checksum = ~th->tcp_csum;\n-                    uint32_t tcp_checksum = old_tcp_checksum + delta_checksum;\n-\n-                    tcp_checksum = csum_finish(tcp_checksum);\n-                    th->tcp_csum = tcp_checksum;\n-                }\n-            } else if (proto == IPPROTO_ICMPV6 &&\n-                       l4_size >= sizeof(struct icmp6_header)) {\n-                delta_checksum = avx512_ipv6_addr_csum_delta(v_packet,\n-                                                             v_new_hdr,\n-                                                             rh_present);\n-                struct icmp6_header *icmp = dp_packet_l4(packet);\n-                uint16_t old_icmp6_checksum = ~icmp->icmp6_cksum;\n-                uint32_t icmp6_checksum = old_icmp6_checksum + delta_checksum;\n-\n-                icmp6_checksum = csum_finish(icmp6_checksum);\n-                icmp->icmp6_cksum = icmp6_checksum;\n-            }\n-\n-            pkt_metadata_init_conn(&packet->md);\n-        }\n-        /* Write back the modified IPv6 addresses. */\n-        _mm512_mask_storeu_epi64((void *) nh, 0x1F, v_new_hdr);\n-\n-        /* Scalar method for setting IPv6 tclass field. */\n-        if (key->ipv6_tclass) {\n-            uint8_t old_tc = ntohl(get_16aligned_be32(&nh->ip6_flow)) >> 20;\n-            uint8_t key_tc = key->ipv6_tclass | (old_tc & ~mask->ipv6_tclass);\n-\n-            packet_set_ipv6_tc(&nh->ip6_flow, key_tc);\n-        }\n-    }\n-}\n-#endif /* HAVE_AVX512VBMI */\n-\n-static void\n-action_avx512_set_masked(struct dp_packet_batch *batch, const struct nlattr *a)\n-{\n-    const struct nlattr *mask = nl_attr_get(a);\n-    enum ovs_key_attr attr_type = nl_attr_type(mask);\n-\n-    if (attr_type <= OVS_KEY_ATTR_MAX && impl_set_masked_funcs[attr_type]) {\n-        impl_set_masked_funcs[attr_type](batch, a);\n-    } else {\n-        odp_execute_scalar_action(batch, a);\n-    }\n-}\n-\n-int\n-action_avx512_init(struct odp_execute_action_impl *self OVS_UNUSED)\n-{\n-    if (!action_avx512_isa_probe()) {\n-        return -ENOTSUP;\n-    }\n-\n-    /* Set function pointers for actions that can be applied directly, these\n-     * are identified by OVS_ACTION_ATTR_*. */\n-    self->funcs[OVS_ACTION_ATTR_POP_VLAN] = action_avx512_pop_vlan;\n-    self->funcs[OVS_ACTION_ATTR_PUSH_VLAN] = action_avx512_push_vlan;\n-    self->funcs[OVS_ACTION_ATTR_SET_MASKED] = action_avx512_set_masked;\n-\n-    /* Set function pointers for the individual operations supported by the\n-     * SET_MASKED action. */\n-    impl_set_masked_funcs[OVS_KEY_ATTR_ETHERNET] = action_avx512_eth_set_addrs;\n-    impl_set_masked_funcs[OVS_KEY_ATTR_IPV4] = action_avx512_ipv4_set_addrs;\n-\n-#if HAVE_AVX512VBMI\n-    if (action_avx512vbmi_isa_probe()) {\n-        impl_set_masked_funcs[OVS_KEY_ATTR_IPV6] = action_avx512_set_ipv6;\n-    }\n-#endif\n-\n-    return 0;\n-}\n-\n-#endif /* Sparse */\n-\n-#else /* __x86_64__ */\n-\n-#include <config.h>\n-#include <errno.h>\n-#include \"odp-execute-private.h\"\n-/* Function itself is required to be called, even in e.g. 32-bit builds.\n- * This dummy init function ensures 32-bit builds succeed too.\n- */\n-\n-int\n-action_avx512_init(struct odp_execute_action_impl *self OVS_UNUSED)\n-{\n-  return -ENOTSUP;\n-}\n-\n-#endif\ndiff --git a/lib/odp-execute-private.c b/lib/odp-execute-private.c\ndeleted file mode 100644\nindex 8b7a6b4ab..000000000\n--- a/lib/odp-execute-private.c\n+++ /dev/null\n@@ -1,294 +0,0 @@\n-/*\n- * Copyright (c) 2022 Intel.\n- *\n- * Licensed under the Apache License, Version 2.0 (the \"License\");\n- * you may not use this file except in compliance with the License.\n- * You may obtain a copy of the License at:\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-\n-#include <config.h>\n-#include <errno.h>\n-#include <stdio.h>\n-#include <string.h>\n-\n-#include \"cpu.h\"\n-#include \"dpdk.h\"\n-#include \"dp-packet.h\"\n-#include \"odp-execute.h\"\n-#include \"odp-execute-private.h\"\n-#include \"odp-netlink.h\"\n-#include \"odp-util.h\"\n-#include \"openvswitch/vlog.h\"\n-\n-VLOG_DEFINE_THIS_MODULE(odp_execute_impl);\n-static int active_action_impl_index;\n-\n-#if ACTION_IMPL_AVX512_CHECK\n-/* Probe functions to check ISA requirements. */\n-bool\n-action_avx512_isa_probe(void)\n-{\n-    static enum ovs_cpu_isa isa_required[] = {\n-        OVS_CPU_ISA_X86_AVX512F,\n-        OVS_CPU_ISA_X86_AVX512BW,\n-        OVS_CPU_ISA_X86_BMI2,\n-        OVS_CPU_ISA_X86_AVX512VL,\n-    };\n-    for (int i = 0; i < ARRAY_SIZE(isa_required); i++) {\n-        if (!cpu_has_isa(isa_required[i])) {\n-            return false;\n-        }\n-    }\n-    return true;\n-}\n-\n-#else\n-\n-bool\n-action_avx512_isa_probe(void)\n-{\n-   return false;\n-}\n-\n-#endif\n-\n-#if ACTION_IMPL_AVX512_CHECK && HAVE_AVX512VBMI\n-bool\n-action_avx512vbmi_isa_probe(void)\n-{\n-    return cpu_has_isa(OVS_CPU_ISA_X86_AVX512VBMI);\n-}\n-#else\n-bool\n-action_avx512vbmi_isa_probe(void)\n-{\n-    return false;\n-}\n-#endif\n-\n-static struct odp_execute_action_impl action_impls[] = {\n-    [ACTION_IMPL_AUTOVALIDATOR] = {\n-        .available = false,\n-        .name = \"autovalidator\",\n-        .init_func = action_autoval_init,\n-    },\n-\n-    [ACTION_IMPL_SCALAR] = {\n-        .available = false,\n-        .name = \"scalar\",\n-        .init_func = odp_action_scalar_init,\n-    },\n-\n-#if ACTION_IMPL_AVX512_CHECK\n-    [ACTION_IMPL_AVX512] = {\n-        .available = false,\n-        .name = \"avx512\",\n-        .init_func = action_avx512_init,\n-    },\n-#endif\n-};\n-\n-static void\n-action_impl_copy_funcs(struct odp_execute_action_impl *dest,\n-                       const struct odp_execute_action_impl *src)\n-{\n-    for (int i = 0; i < __OVS_ACTION_ATTR_MAX; i++) {\n-        atomic_store_relaxed(&dest->funcs[i], src->funcs[i]);\n-    }\n-}\n-\n-struct odp_execute_action_impl *\n-odp_execute_action_set(const char *name)\n-{\n-    for (int i = 0; i < ACTION_IMPL_MAX; i++) {\n-        /* String compare, and set ptrs atomically. */\n-        if (!strcmp(action_impls[i].name, name)) {\n-            if (i != active_action_impl_index) {\n-                active_action_impl_index = i;\n-                VLOG_INFO(\"Action implementation set to %s\", name);\n-            }\n-            return &action_impls[i];\n-        }\n-    }\n-    return NULL;\n-}\n-\n-void\n-odp_execute_action_get_info(struct ds *string)\n-{\n-    ds_put_cstr(string, \"Available Actions implementations:\\n\");\n-    for (int i = 0; i < ACTION_IMPL_MAX; i++) {\n-        ds_put_format(string, \"  %s (available: %s, active: %s)\\n\",\n-                      action_impls[i].name,\n-                      action_impls[i].available ? \"Yes\" : \"No\",\n-                      i == active_action_impl_index ? \"Yes\" : \"No\");\n-    }\n-}\n-\n-void\n-odp_execute_action_init(void)\n-{\n-    /* Each impl's function array is initialized to reflect the scalar\n-     * implementation. This simplifies adding optimized implementations,\n-     * as the autovalidator can always compare all actions.\n-     *\n-     * Below will check if impl is available and copies the scalar functions\n-     * to all other implementations. */\n-    for (int i = 0; i < ACTION_IMPL_MAX; i++) {\n-        bool avail = true;\n-\n-        if (i != ACTION_IMPL_SCALAR) {\n-            action_impl_copy_funcs(&action_impls[i],\n-                                   &action_impls[ACTION_IMPL_SCALAR]);\n-        }\n-\n-        if (action_impls[i].init_func) {\n-            /* Return zero is success, non-zero means error. */\n-            avail = (action_impls[i].init_func(&action_impls[i]) == 0);\n-        }\n-\n-        action_impls[i].available = avail;\n-\n-        VLOG_DBG(\"Actions implementation '%s' %s available.\",\n-                 action_impls[i].name, avail ? \"is\" : \"is not\");\n-\n-        /* The following is a run-time check to make sure a scalar\n-         * implementation exists for the given ISA implementation. This is to\n-         * make sure the autovalidator works as expected. */\n-        if (avail && i != ACTION_IMPL_SCALAR) {\n-            for (int j = 0; j < __OVS_ACTION_ATTR_MAX; j++) {\n-                /* No ovs_assert(), as it can be compiled out. */\n-                if (action_impls[ACTION_IMPL_SCALAR].funcs[j] == NULL\n-                    && action_impls[i].funcs[j] != NULL) {\n-                    ovs_assert_failure(OVS_SOURCE_LOCATOR, __func__,\n-                                       \"Missing scalar action function!\");\n-                }\n-            }\n-        }\n-    }\n-}\n-\n-/* Init sequence required to be scalar first to pick up the default scalar\n- * implementations, allowing over-riding of the optimized functions later. */\n-BUILD_ASSERT_DECL(ACTION_IMPL_SCALAR == 0);\n-BUILD_ASSERT_DECL(ACTION_IMPL_AUTOVALIDATOR == 1);\n-\n-/* Loop over packets, and validate each one for the given action. */\n-static void\n-action_autoval_generic(struct dp_packet_batch *batch, const struct nlattr *a)\n-{\n-    struct odp_execute_action_impl *scalar = &action_impls[ACTION_IMPL_SCALAR];\n-    enum ovs_action_attr attr_type = nl_attr_type(a);\n-    struct dp_packet_batch original_batch;\n-    bool failed = false;\n-\n-    dp_packet_batch_clone(&original_batch, batch);\n-\n-    scalar->funcs[attr_type](batch, a);\n-\n-    for (int impl = ACTION_IMPL_BEGIN; impl < ACTION_IMPL_MAX; impl++) {\n-        /* Clone original batch and execute implementation under test. */\n-        struct dp_packet_batch test_batch;\n-\n-        dp_packet_batch_clone(&test_batch, &original_batch);\n-        action_impls[impl].funcs[attr_type](&test_batch, a);\n-\n-        /* Loop over implementations, checking each one. */\n-        for (int pidx = 0; pidx < original_batch.count; pidx++) {\n-            struct dp_packet *good_pkt = batch->packets[pidx];\n-            struct dp_packet *test_pkt = test_batch.packets[pidx];\n-\n-            struct ds log_msg = DS_EMPTY_INITIALIZER;\n-\n-            /* Compare packet length and payload contents. */\n-            bool eq = dp_packet_equal(good_pkt, test_pkt);\n-\n-            if (!eq) {\n-                ds_put_format(&log_msg, \"Packet: %d\\nAction : \", pidx);\n-                format_odp_actions(&log_msg, a, a->nla_len, NULL);\n-                ds_put_format(&log_msg, \"\\nGood hex:\\n\");\n-                ds_put_hex_dump(&log_msg, dp_packet_data(good_pkt),\n-                                dp_packet_size(good_pkt), 0, false);\n-                ds_put_format(&log_msg, \"Test hex:\\n\");\n-                ds_put_hex_dump(&log_msg, dp_packet_data(test_pkt),\n-                                dp_packet_size(test_pkt), 0, false);\n-\n-                failed = true;\n-            }\n-\n-            /* Compare offsets and RSS */\n-            if (!dp_packet_compare_offsets(good_pkt, test_pkt, &log_msg)) {\n-                failed = true;\n-            }\n-\n-            if (dp_packet_rss_valid(good_pkt)) {\n-                uint32_t good_hash = dp_packet_get_rss_hash(good_pkt);\n-                uint32_t test_hash = dp_packet_get_rss_hash(test_pkt);\n-\n-                if (good_hash != test_hash) {\n-                    ds_put_format(&log_msg,\n-                                  \"Autovalidation rss hash failed\\n\");\n-                    ds_put_format(&log_msg, \"Good RSS hash : %u\\n\", good_hash);\n-                    ds_put_format(&log_msg, \"Test RSS hash : %u\\n\", test_hash);\n-\n-                    failed = true;\n-                }\n-            }\n-\n-            /* Compare packet metadata. */\n-            if (memcmp(&good_pkt->md, &test_pkt->md, sizeof good_pkt->md)) {\n-                ds_put_format(&log_msg, \"Autovalidation metadata failed\\n\");\n-                ds_put_format(&log_msg, \"Good packet metadata:\\n\");\n-                ds_put_sparse_hex_dump(&log_msg, &good_pkt->md,\n-                                       sizeof good_pkt->md, 0, false);\n-                ds_put_format(&log_msg, \"Test packet metadata:\\n\");\n-                ds_put_sparse_hex_dump(&log_msg, &test_pkt->md,\n-                                       sizeof test_pkt->md, 0, false);\n-                failed = true;\n-            }\n-\n-            if (failed) {\n-                VLOG_ERR(\"Autovalidation of %s failed. Details:\\n%s\",\n-                         action_impls[impl].name, ds_cstr(&log_msg));\n-                ds_destroy(&log_msg);\n-                failed = false;\n-            }\n-        }\n-        dp_packet_delete_batch(&test_batch, true);\n-    }\n-    dp_packet_delete_batch(&original_batch, true);\n-}\n-\n-void\n-odp_execute_scalar_action(struct dp_packet_batch *batch,\n-                          const struct nlattr *action)\n-{\n-    enum ovs_action_attr type = nl_attr_type(action);\n-\n-    if (type <= OVS_ACTION_ATTR_MAX &&\n-        action_impls[ACTION_IMPL_SCALAR].funcs[type]) {\n-\n-        action_impls[ACTION_IMPL_SCALAR].funcs[type](batch, action);\n-    }\n-}\n-\n-int\n-action_autoval_init(struct odp_execute_action_impl *self)\n-{\n-    /* Set function pointers for actions that can be applied directly, these\n-     * are identified by OVS_ACTION_ATTR_*. */\n-    for (int i = 0; i < __OVS_ACTION_ATTR_MAX; i++) {\n-        if (action_impls[ACTION_IMPL_SCALAR].funcs[i]) {\n-            self->funcs[i] = action_autoval_generic;\n-        }\n-    }\n-    return 0;\n-}\ndiff --git a/lib/odp-execute-private.h b/lib/odp-execute-private.h\ndeleted file mode 100644\nindex 643f41c2a..000000000\n--- a/lib/odp-execute-private.h\n+++ /dev/null\n@@ -1,103 +0,0 @@\n-/*\n- * Copyright (c) 2022 Intel.\n- *\n- * Licensed under the Apache License, Version 2.0 (the \"License\");\n- * you may not use this file except in compliance with the License.\n- * You may obtain a copy of the License at:\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-\n-#ifndef ODP_EXTRACT_PRIVATE\n-#define ODP_EXTRACT_PRIVATE 1\n-\n-#include \"dp-packet.h\"\n-#include \"odp-execute.h\"\n-#include \"odp-netlink.h\"\n-#include \"ovs-atomic.h\"\n-\n-/* Combine all required ISA and Linker checks into a single #define\n- * for readability and simplicity where the checks are needed. Note\n- * that it is always #defined, so code must use the #if preprocesor\n- * directive (not #ifdef). */\n-#define ACTION_IMPL_AVX512_CHECK (__x86_64__ && HAVE_AVX512F \\\n-    && HAVE_LD_AVX512_GOOD && __SSE4_2__ && HAVE_AVX512BW && HAVE_AVX512VL \\\n-    && HAVE_GCC_AVX512VL_GOOD)\n-\n-/* Forward declaration for typedef. */\n-struct odp_execute_action_impl;\n-\n-/* Typedef for an initialization function that can initialize each\n- * implementation, checking requirements such as CPU ISA. */\n-typedef int (*odp_execute_action_init_func)\n-                    (struct odp_execute_action_impl *self);\n-\n-/* Structure represents an implementation of the odp actions. */\n-struct odp_execute_action_impl {\n-    /* When set, the CPU ISA required for this implementation is available\n-     * and the implementation can be used. */\n-    bool available;\n-\n-    /* Name of the implementation. */\n-    const char *name;\n-\n-    /* Function is used to detect if this CPU has the ISA required\n-     * to run the optimized action implementation and if available, initializes\n-     * the implementation for use. */\n-    odp_execute_action_init_func init_func;\n-\n-    /* An array of callback functions, one for each action. */\n-    ATOMIC(odp_execute_action_cb) funcs[__OVS_ACTION_ATTR_MAX];\n-};\n-\n-/* Order of Actions implementations. */\n-enum odp_execute_action_impl_idx {\n-    ACTION_IMPL_SCALAR,\n-    ACTION_IMPL_AUTOVALIDATOR,\n-    /* See ACTION_IMPL_BEGIN below, for \"first to-be-validated\" impl.\n-     * Do not change the autovalidator position in this list without updating\n-     * the define below. */\n-\n-#if ACTION_IMPL_AVX512_CHECK\n-    ACTION_IMPL_AVX512,\n-#endif\n-\n-    ACTION_IMPL_MAX,\n-};\n-\n-/* Index to start verifying implementations from. */\n-BUILD_ASSERT_DECL(ACTION_IMPL_SCALAR == 0);\n-BUILD_ASSERT_DECL(ACTION_IMPL_AUTOVALIDATOR == 1);\n-\n-#define ACTION_IMPL_BEGIN (ACTION_IMPL_AUTOVALIDATOR + 1)\n-\n-bool action_avx512_isa_probe(void);\n-bool action_avx512vbmi_isa_probe(void);\n-\n-/* Odp execute init handles setting up the state of the actions functions at\n- * initialization time. It cannot return errors, as it must always succeed in\n- * initializing the scalar/generic codepath. */\n-void odp_execute_action_init(void);\n-\n-/* Init functions for the action implementations. Initializes the function\n- * pointers for optimized action types. */\n-int odp_action_scalar_init(struct odp_execute_action_impl *self);\n-\n-struct odp_execute_action_impl * odp_execute_action_set(const char *name);\n-\n-int action_autoval_init(struct odp_execute_action_impl *self);\n-\n-int action_avx512_init(struct odp_execute_action_impl *self);\n-\n-void odp_execute_action_get_info(struct ds *name);\n-\n-void odp_execute_scalar_action(struct dp_packet_batch *batch,\n-                               const struct nlattr *action);\n-\n-#endif /* ODP_EXTRACT_PRIVATE */\ndiff --git a/lib/odp-execute-unixctl.man b/lib/odp-execute-unixctl.man\ndeleted file mode 100644\nindex 82d51e1d3..000000000\n--- a/lib/odp-execute-unixctl.man\n+++ /dev/null\n@@ -1,10 +0,0 @@\n-.SS \"ODP-EXECUTE COMMANDS\"\n-These commands manage the \"odp-execute\" component.\n-\n-.IP \"\\fBodp-execute/action-impl-show\\fR\n-Lists the actions implementations that are available and highlights the\n-currently enabled one.\n-.\n-.IP \"\\fBodp-execute/action-impl-set\\fR \\fIaction_impl\\fR\"\n-Sets the action implementation to any available implementation. By default\n-\"scalar\" is used.\ndiff --git a/lib/odp-execute.c b/lib/odp-execute.c\nindex ecbda8c01..4642f3375 100644\n--- a/lib/odp-execute.c\n+++ b/lib/odp-execute.c\n@@ -17,7 +17,6 @@\n \n #include <config.h>\n #include \"odp-execute.h\"\n-#include \"odp-execute-private.h\"\n #include <sys/types.h>\n #include <netinet/in.h>\n #include <arpa/inet.h>\n@@ -914,130 +913,6 @@ requires_datapath_assistance(const struct nlattr *a)\n     return false;\n }\n \n-static void\n-action_pop_vlan(struct dp_packet_batch *batch,\n-                const struct nlattr *a OVS_UNUSED)\n-{\n-    struct dp_packet *packet;\n-\n-    DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {\n-        eth_pop_vlan(packet);\n-    }\n-}\n-\n-static void\n-action_push_vlan(struct dp_packet_batch *batch, const struct nlattr *a)\n-{\n-    struct dp_packet *packet;\n-    const struct ovs_action_push_vlan *vlan = nl_attr_get(a);\n-\n-    DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {\n-        eth_push_vlan(packet, vlan->vlan_tpid, vlan->vlan_tci);\n-    }\n-}\n-\n-static void\n-action_set_masked(struct dp_packet_batch *batch, const struct nlattr *a)\n-{\n-    const struct nlattr *key = nl_attr_get(a);\n-    struct dp_packet *packet;\n-\n-    DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {\n-        odp_execute_masked_set_action(packet, key);\n-    }\n-}\n-\n-/* Implementation of the scalar actions impl init function. Build up the\n- * array of func ptrs here. */\n-int\n-odp_action_scalar_init(struct odp_execute_action_impl *self)\n-{\n-    /* Set function pointers for actions that can be applied directly, these\n-     * are identified by OVS_ACTION_ATTR_*. */\n-    self->funcs[OVS_ACTION_ATTR_POP_VLAN] = action_pop_vlan;\n-    self->funcs[OVS_ACTION_ATTR_PUSH_VLAN] = action_push_vlan;\n-    self->funcs[OVS_ACTION_ATTR_SET_MASKED] = action_set_masked;\n-\n-    return 0;\n-}\n-\n-/* The active function pointers on the datapath. ISA optimized implementations\n- * are enabled by plugging them into this static arary, which is consulted when\n- * applying actions on the datapath. */\n-static ATOMIC(struct odp_execute_action_impl *) actions_active_impl;\n-\n-static int\n-odp_actions_impl_set(const char *name)\n-{\n-    struct odp_execute_action_impl *active;\n-    active = odp_execute_action_set(name);\n-    if (!active) {\n-        VLOG_ERR(\"Failed setting action implementation to %s\", name);\n-        return 1;\n-    }\n-\n-    atomic_store_relaxed(&actions_active_impl, active);\n-    return 0;\n-}\n-\n-static void\n-action_impl_set(struct unixctl_conn *conn, int argc OVS_UNUSED,\n-                const char *argv[], void *aux OVS_UNUSED)\n-{\n-    struct ds reply = DS_EMPTY_INITIALIZER;\n-\n-    int err = odp_actions_impl_set(argv[1]);\n-    if (err) {\n-        ds_put_format(&reply,\n-                      \"Error: unknown action implementation, %s, specified!\",\n-                      argv[1]);\n-        unixctl_command_reply_error(conn, ds_cstr(&reply));\n-    } else {\n-        ds_put_format(&reply, \"Action implementation set to %s.\", argv[1]);\n-        unixctl_command_reply(conn, ds_cstr(&reply));\n-    }\n-\n-    ds_destroy(&reply);\n-}\n-\n-static void\n-action_impl_show(struct unixctl_conn *conn, int argc OVS_UNUSED,\n-                const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)\n-{\n-    struct ds reply = DS_EMPTY_INITIALIZER;\n-\n-    odp_execute_action_get_info(&reply);\n-    unixctl_command_reply(conn, ds_cstr(&reply));\n-    ds_destroy(&reply);\n-}\n-\n-static void\n-odp_execute_unixctl_init(void)\n-{\n-    unixctl_command_register(\"odp-execute/action-impl-set\", \"name\",\n-                             1, 1, action_impl_set,\n-                             NULL);\n-    unixctl_command_register(\"odp-execute/action-impl-show\", \"\",\n-                             0, 0, action_impl_show,\n-                             NULL);\n-}\n-\n-void\n-odp_execute_init(void)\n-{\n-    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;\n-    if (ovsthread_once_start(&once)) {\n-        odp_execute_action_init();\n-#ifdef ACTIONS_AUTOVALIDATOR_DEFAULT\n-        odp_actions_impl_set(\"autovalidator\");\n-#else\n-        odp_actions_impl_set(\"scalar\");\n-#endif\n-        odp_execute_unixctl_init();\n-        ovsthread_once_done(&once);\n-    }\n-}\n-\n /* Executes all of the 'actions_len' bytes of datapath actions in 'actions' on\n  * the packets in 'batch'.  If 'steal' is true, possibly modifies and\n  * definitely free the packets in 'batch', otherwise leaves 'batch' unchanged.\n@@ -1085,25 +960,22 @@ odp_execute_actions(void *dp, struct dp_packet_batch *batch, bool steal,\n             continue;\n         }\n \n-        /* If type is set in the active actions implementation, call the\n-         * function-pointer and continue to the next action. */\n-        if (attr_type <= OVS_ACTION_ATTR_MAX) {\n-            /* Read the action implementation pointer atomically to avoid\n-             * non-atomic read causing corruption if being written by another\n-             * thread simultaneously. */\n-            struct odp_execute_action_impl *actions_impl;\n-            atomic_read_relaxed(&actions_active_impl, &actions_impl);\n-\n-            if (actions_impl && actions_impl->funcs[attr_type]) {\n-                actions_impl->funcs[attr_type](batch, a);\n-                continue;\n+        switch (attr_type) {\n+        case OVS_ACTION_ATTR_POP_VLAN:\n+            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {\n+                eth_pop_vlan(packet);\n+            }\n+            break;\n+\n+        case OVS_ACTION_ATTR_PUSH_VLAN: {\n+            const struct ovs_action_push_vlan *vlan = nl_attr_get(a);\n+\n+            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {\n+                eth_push_vlan(packet, vlan->vlan_tpid, vlan->vlan_tci);\n             }\n+            break;\n         }\n \n-        /* If the action was not handled by the active function pointers above,\n-         * process them by switching on the type below. */\n-\n-        switch (attr_type) {\n         case OVS_ACTION_ATTR_HASH: {\n             const struct ovs_action_hash *hash_act = nl_attr_get(a);\n \n@@ -1171,6 +1043,12 @@ odp_execute_actions(void *dp, struct dp_packet_batch *batch, bool steal,\n             }\n             break;\n \n+        case OVS_ACTION_ATTR_SET_MASKED:\n+            DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {\n+                odp_execute_masked_set_action(packet, nl_attr_get(a));\n+            }\n+            break;\n+\n         case OVS_ACTION_ATTR_SAMPLE:\n             DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {\n                 odp_execute_sample(dp, packet, steal && last_action, a,\n@@ -1296,15 +1174,8 @@ odp_execute_actions(void *dp, struct dp_packet_batch *batch, bool steal,\n         case OVS_ACTION_ATTR_DEC_TTL:\n         case OVS_ACTION_ATTR_PSAMPLE:\n         case __OVS_ACTION_ATTR_MAX:\n-        /* The following actions are handled by the scalar implementation. */\n-        case OVS_ACTION_ATTR_POP_VLAN:\n-        case OVS_ACTION_ATTR_PUSH_VLAN:\n-        case OVS_ACTION_ATTR_SET_MASKED:\n             OVS_NOT_REACHED();\n         }\n-\n-        /* Do not add any generic processing here, as it won't be executed when\n-         * an ISA-specific action implementation exists. */\n     }\n \n     dp_packet_delete_batch(batch, steal);\ndiff --git a/lib/odp-execute.h b/lib/odp-execute.h\nindex 2ba1ec5d2..7a54fa6ec 100644\n--- a/lib/odp-execute.h\n+++ b/lib/odp-execute.h\n@@ -24,17 +24,8 @@\n #include \"openvswitch/types.h\"\n \n struct nlattr;\n-struct dp_packet;\n-struct pkt_metadata;\n struct dp_packet_batch;\n \n-\n-/* Called once at initialization time. */\n-void odp_execute_init(void);\n-\n-typedef void (*odp_execute_action_cb)(struct dp_packet_batch *batch,\n-                                      const struct nlattr *action);\n-\n typedef void (*odp_execute_cb)(void *dp, struct dp_packet_batch *batch,\n                                const struct nlattr *action, bool should_steal);\n \ndiff --git a/m4/openvswitch.m4 b/m4/openvswitch.m4\nindex 060070475..ca3deec9a 100644\n--- a/m4/openvswitch.m4\n+++ b/m4/openvswitch.m4\n@@ -410,34 +410,6 @@ AC_DEFUN([OVS_CHECK_SPHINX],\n    AM_CONDITIONAL([HAVE_SPHINX], [test \"$SPHINXBUILD\" != none])])\n \n \n-dnl Checks for compiler correctly emitting AVX512-VL vpermd instruction.\n-dnl GCC5 says it exports AVX512-VL, but it doesn't implement \"vpermd\" instruction\n-dnl resulting in compilation failures. To workaround this \"reported vs actual\"\n-dnl mismatch, we compile a small snippet, and conditionally enable AVX512-VL.\n-AC_DEFUN([OVS_CHECK_GCC_AVX512VL], [\n-  AC_MSG_CHECKING([whether compiler correctly emits AVX512-VL])\n-  AC_COMPILE_IFELSE(\n-    [AC_LANG_PROGRAM([#include <immintrin.h>\n-                     static void __attribute__((__target__(\"avx512vl\")))\n-                     check_permutexvar(void)\n-                     {\n-                         __m256i v_swap32a = _mm256_setr_epi32(0x0, 0x4, 0xF,\n-                                                               0xF, 0xF, 0xF,\n-                                                               0xF, 0xF);\n-                         v_swap32a = _mm256_permutexvar_epi32(v_swap32a,\n-                                                              v_swap32a);\n-                     }],[])],\n-    [AC_MSG_RESULT([yes])\n-    ovs_cv_gcc_avx512vl_good=yes],\n-    [AC_MSG_RESULT([no])\n-    ovs_cv_gcc_avx512vl_good=no])\n-   if test \"$ovs_cv_gcc_avx512vl_good\" = yes; then\n-     AC_DEFINE([HAVE_GCC_AVX512VL_GOOD], [1],\n-               [Define to 1 if gcc implements the vpermd instruction.])\n-   fi\n-   AM_CONDITIONAL([HAVE_GCC_AVX512VL_GOOD],\n-                  [test \"$ovs_cv_gcc_avx512vl_good\" = yes])])\n-\n dnl Checks whether the build system implements the vpopcntdq instruction. The\n dnl compiler and assembler each separately need to support vpopcntdq. In order\n dnl to test the assembler with the below code snippet, set the optimization\ndiff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at\nindex 231197970..005c1991a 100644\n--- a/tests/dpif-netdev.at\n+++ b/tests/dpif-netdev.at\n@@ -3650,62 +3650,3 @@ OVS_VSWITCHD_STOP([\"dnl\n /Error: unknown miniflow extract implementation superstudy./d\n /Error: invalid study_pkt_cnt value: -pmd./d\"])\n AT_CLEANUP\n-\n-AT_SETUP([datapath - Actions Autovalidator Checksum])\n-\n-OVS_VSWITCHD_START(add-port br0 p0 -- set Interface p0 type=dummy \\\n-                   -- add-port br0 p1 -- set Interface p1 type=dummy)\n-\n-AT_CHECK([ovs-appctl odp-execute/action-impl-set autovalidator], [0], [dnl\n-Action implementation set to autovalidator.\n-])\n-\n-dnl Add flows to trigger checksum calculation.\n-AT_DATA([flows.txt], [dnl\n-  in_port=p0,ip,actions=mod_nw_src=10.1.1.1,p1\n-  in_port=p0,ipv6,actions=set_field:fc00::100->ipv6_src,p1\n-])\n-AT_CHECK([ovs-ofctl del-flows br0])\n-AT_CHECK([ovs-ofctl -Oopenflow13 add-flows br0 flows.txt])\n-\n-AT_CHECK([ovs-vsctl set Interface p1 options:pcap=p1.pcap])\n-\n-dnl IPv4 packet with values that will trigger carry-over addition for checksum.\n-flow_s_v4=\"\n-  eth_src=47:42:86:08:17:50,eth_dst=3e:55:b5:9e:3a:fb,dl_type=0x0800,\n-  nw_src=229.167.36.90,nw_dst=130.161.64.186,nw_proto=6,nw_ttl=64,nw_frag=no,\n-  tp_src=54392,tp_dst=5201,tcp_flags=ack\"\n-\n-good_frame=$(ovs-ofctl compose-packet --bare \"${flow_s_v4}\")\n-AT_CHECK([ovs-appctl netdev-dummy/receive p0 ${good_frame}])\n-\n-dnl Checksum should change to 0xAC33 with ip_src changed to 10.1.1.1\n-dnl by the datapath while processing the packet.\n-flow_expected=$(echo \"${flow_s_v4}\" | sed 's/229.167.36.90/10.1.1.1/g')\n-good_expected=$(ovs-ofctl compose-packet --bare \"${flow_expected}\")\n-AT_CHECK([ovs-pcap p1.pcap > p1.pcap.txt 2>&1])\n-AT_CHECK_UNQUOTED([tail -n 1 p1.pcap.txt], [0], [${good_expected}\n-])\n-\n-dnl Repeat similar test for IPv6.\n-flow_s_v6=\"\n-  eth_src=8a:bf:7e:2f:05:84,eth_dst=0a:8f:39:4f:e0:73,dl_type=0x86dd,\n-  ipv6_src=2f8a:2076:3926:9e7:2d47:4bc9:9c7:17f3,\n-  ipv6_dst=7287:10dd:2fb9:41d5:3eb2:2c7a:11b0:6258,\n-  ipv6_label=0x51ac,nw_proto=6,nw_ttl=142,nw_frag=no,\n-  tp_src=20405,tp_dst=20662,tcp_flags=ack\"\n-\n-good_frame_v6=$(ovs-ofctl compose-packet --bare \"${flow_s_v6}\")\n-AT_CHECK([ovs-appctl netdev-dummy/receive p0 ${good_frame_v6}])\n-\n-dnl Checksum should change to 0x59FD with ipv6_src changed to fc00::100\n-dnl by the datapath while processing the packet.\n-flow_expected_v6=$(echo \"${flow_s_v6}\" | \\\n-  sed 's/2f8a:2076:3926:9e7:2d47:4bc9:9c7:17f3/fc00::100/g')\n-good_expected_v6=$(ovs-ofctl compose-packet --bare \"${flow_expected_v6}\")\n-AT_CHECK([ovs-pcap p1.pcap > p1.pcap.txt 2>&1])\n-AT_CHECK_UNQUOTED([tail -n 1 p1.pcap.txt], [0], [${good_expected_v6}\n-])\n-\n-OVS_VSWITCHD_STOP\n-AT_CLEANUP\ndiff --git a/tests/odp.at b/tests/odp.at\nindex 402b2386d..e7d8ad565 100644\n--- a/tests/odp.at\n+++ b/tests/odp.at\n@@ -504,42 +504,3 @@ AT_CHECK_UNQUOTED([ovstest test-odp parse-keys < odp-in.txt], [0], [dnl\n odp_flow_from_string: error (syntax error at encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap(encap())))))))))))))))))))))))))))))))))\n ])\n AT_CLEANUP\n-\n-AT_BANNER([datapath actions in userspace])\n-AT_SETUP([odp-execute - actions implementation])\n-OVS_VSWITCHD_START()\n-\n-AT_CHECK([ovs-vsctl show], [], [stdout])\n-\n-dnl Set the scalar first, so we always have the scalar impl as Active.\n-AT_CHECK([ovs-appctl odp-execute/action-impl-set scalar], [0], [dnl\n-Action implementation set to scalar.\n-])\n-AT_CHECK([ovs-appctl odp-execute/action-impl-show | grep \"scalar\"], [], [dnl\n-  scalar (available: Yes, active: Yes)\n-])\n-\n-AT_CHECK([ovs-appctl odp-execute/action-impl-show | grep \"autovalidator\"], [], [dnl\n-  autovalidator (available: Yes, active: No)\n-])\n-\n-dnl Set the autovalidator impl to active.\n-AT_CHECK([ovs-appctl odp-execute/action-impl-set autovalidator], [0], [dnl\n-Action implementation set to autovalidator.\n-])\n-\n-AT_CHECK([ovs-appctl odp-execute/action-impl-show | grep \"scalar\"], [], [dnl\n-  scalar (available: Yes, active: No)\n-])\n-\n-AT_CHECK([ovs-appctl odp-execute/action-impl-show | grep \"autovalidator\"], [], [dnl\n-  autovalidator (available: Yes, active: Yes)\n-])\n-\n-AT_CHECK([ovs-appctl odp-execute/action-impl-set invalid_implementation], [2], [], [dnl\n-Error: unknown action implementation, invalid_implementation, specified!\n-ovs-appctl: ovs-vswitchd: server returned an error\n-])\n-\n-OVS_VSWITCHD_STOP([\"/Failed setting action implementation to invalid_implementation/d\"])\n-AT_CLEANUP\ndiff --git a/vswitchd/bridge.c b/vswitchd/bridge.c\nindex 7a68e19ac..38435e9ab 100644\n--- a/vswitchd/bridge.c\n+++ b/vswitchd/bridge.c\n@@ -532,7 +532,6 @@ bridge_init(const char *remote)\n     stp_init();\n     lldp_init();\n     rstp_init();\n-    odp_execute_init();\n \n     ifaces_changed = seq_create();\n     last_ifaces_changed = seq_read(ifaces_changed);\ndiff --git a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in\nindex 98e58951d..d90bdddbc 100644\n--- a/vswitchd/ovs-vswitchd.8.in\n+++ b/vswitchd/ovs-vswitchd.8.in\n@@ -292,7 +292,6 @@ type).\n .so lib/dpif-netdev-unixctl.man\n .so lib/dpif-netlink-unixctl.man\n .so lib/netdev-dpdk-unixctl.man\n-.so lib/odp-execute-unixctl.man\n .so ofproto/ofproto-dpif-unixctl.man\n .so ofproto/ofproto-unixctl.man\n .so lib/vlog-unixctl.man\n",
    "prefixes": [
        "ovs-dev",
        "1/6"
    ]
}