On 01/05/2026 13:00, Eelco Chaudron wrote:
External email: Use caution opening links or attachments


On 1 Apr 2026, at 11:13, Eli Britstein wrote:

From: Ariel Levkovich <[email protected]>

Add a new option to build ovs with doca by specifying '--with-doca' in the
configure line.

This flag must be used along with '--with-dpdk'. Otherwise the configure step
will fail.

An example:

./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc \
     --with-dpdk=static --with-doca=static

Hi Ariel/Eli,

See comments below.

//Eelco

Co-authored-by: Salem Sol <[email protected]>
Signed-off-by: Salem Sol <[email protected]>
Co-authored-by: Eli Britstein <[email protected]>
Signed-off-by: Eli Britstein <[email protected]>
Signed-off-by: Ariel Levkovich <[email protected]>
---
  .ci/doca-build.sh                    |  36 ++++++
  .ci/doca-install.sh                  |  20 +++
  .github/workflows/build-and-test.yml |  58 +++++++++
  Makefile.am                          |   2 +
  acinclude.m4                         | 174 +++++++++++++++++++++++++++
  configure.ac                         |   1 +
  lib/automake.mk                      |   4 +
  lib/dpdk.h                           |   1 +
  lib/ovs-doca.c                       |  86 +++++++++++++
  lib/ovs-doca.h                       |  31 +++++
  utilities/checkpatch_dict.txt        |   1 +
  vswitchd/bridge.c                    |   5 +
  vswitchd/ovs-vswitchd.c              |   3 +
  vswitchd/vswitch.ovsschema           |   9 +-
  vswitchd/vswitch.xml                 |  10 ++
  15 files changed, 439 insertions(+), 2 deletions(-)
  create mode 100755 .ci/doca-build.sh
  create mode 100755 .ci/doca-install.sh
  create mode 100644 lib/ovs-doca.c
  create mode 100644 lib/ovs-doca.h

diff --git a/.ci/doca-build.sh b/.ci/doca-build.sh
new file mode 100755
index 000000000..ed9dd7dc9
--- /dev/null
+++ b/.ci/doca-build.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+set -o errexit
+set -x
+
+CFLAGS_FOR_OVS="-g -O2"
+EXTRA_OPTS="--enable-Werror"
+JOBS=${JOBS:-"-j4"}
+
+DOCA_LINK="${DOCA_LINK:-static}"
+
+for pc_dir in $(find /opt/mellanox -name pkgconfig -type d 2>/dev/null); do
+    PKG_CONFIG_PATH="${pc_dir}:${PKG_CONFIG_PATH}"
+done
+export PKG_CONFIG_PATH
+
+if [ "$DOCA_LINK" = "shared" ]; then
+    DOCA_LIB=$(find /opt/mellanox -name pkgconfig -type d 2>/dev/null \
+               | head -1 | sed 's|/pkgconfig$||')
+    export LD_LIBRARY_PATH="${DOCA_LIB}:${LD_LIBRARY_PATH}"
+fi
+sudo ldconfig
+
+if [ "$CC" = "clang" ]; then
+    CFLAGS_FOR_OVS="${CFLAGS_FOR_OVS} -Wno-error=unused-command-line-argument"
Why do we need this?  Should the DOCA pkg-config output be fixed
to not emit linker flags during compile steps instead?
Removed.

+fi
+
+EXTRA_OPTS="$EXTRA_OPTS --with-dpdk=$DOCA_LINK --with-doca=$DOCA_LINK"
+
+if [ "$DOCA_LINK" = "shared" ]; then
+    EXTRA_OPTS="$EXTRA_OPTS --enable-shared"
+fi
+
+./boot.sh
+./configure CFLAGS="${CFLAGS_FOR_OVS}" $EXTRA_OPTS
+make $JOBS
It should do make check here, as minimal tests should still pass.
See linux-build.sh for details on how to run it.
I added it, but it failed in some ODP tests, that pass locally for me. I think there is some issue with it. I will keep investigating this but we may have some unrelated noise that I don't want to hold the series for it.

diff --git a/.ci/doca-install.sh b/.ci/doca-install.sh
new file mode 100755
index 000000000..5931bf821
--- /dev/null
+++ b/.ci/doca-install.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+set -ev
+
+# Install DOCA SDK packages.
+#
+# Download the DOCA host repo package from:
+#   https://developer.nvidia.com/doca-downloads
+#     deployment_platform=Host-Server, deployment_package=DOCA-Host,
+#     target_os=Linux, Architecture=x86_64, Profile=doca-all
+#
+
+DOCA_REPO_PKG_URL="${DOCA_REPO_PKG_URL:?Set to .deb repo package URL}"
+
+wget -q "$DOCA_REPO_PKG_URL" -O /tmp/doca-repo.deb
+sudo dpkg -i /tmp/doca-repo.deb
+sudo apt-get update
+sudo apt-get install -y dpdk-community-dev \
+    libdoca-sdk-flow-dev libdoca-sdk-dpdk-bridge-dev
+
diff --git a/.github/workflows/build-and-test.yml 
b/.github/workflows/build-and-test.yml
index f1d006de6..8924d517c 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -699,3 +699,61 @@ jobs:
          path: |
            rpm/rpmbuild/SRPMS/*.rpm
            rpm/rpmbuild/RPMS/*/*.rpm
+
+  build-doca:
+    env:
+      dependencies: |
+        automake libtool gcc bc libssl-dev llvm-dev libnuma-dev \
+        libunbound-dev libunwind-dev libsystemd-dev wget python3-pip
+      DOCA_REPO_PKG_URL: 
"https://www.mellanox.com/downloads/DOCA/DOCA_v3.3.0/host/doca-host_3.3.0-088000-26.01-ubuntu2404_amd64.deb";
+      CC:        ${{ matrix.compiler }}
+      DOCA_LINK: ${{ matrix.doca_link }}
+
+    name: doca ubuntu ${{ matrix.compiler }} ${{ matrix.doca_link }}
+    runs-on: ubuntu-24.04
+    timeout-minutes: 30
+
+    strategy:
+      fail-fast: false
+      matrix:
+        include:
+          - compiler:  gcc
+            doca_link: static
+          - compiler:  gcc
+            doca_link: shared
+          - compiler:  clang
+            doca_link: static
+          - compiler:  clang
+            doca_link: shared
+
+    steps:
+    - name: checkout
+      uses: actions/checkout@v4
+
+    - name: update PATH
+      run:  |
+        echo "$HOME/bin"        >> $GITHUB_PATH
+        echo "$HOME/.local/bin" >> $GITHUB_PATH
+
+    - name: set up python
+      uses: actions/setup-python@v5
+      with:
+        python-version: ${{ env.python_default }}
+
+    - name: update APT cache
+      run:  sudo apt update || true
Need a newline here.
Ack

+    - name: install common dependencies
+      run:  sudo apt install -y ${{ env.dependencies }}
+
+    - name: install DOCA
+      run:  ./.ci/doca-install.sh
We need this to be build against the DPDK_VER version of DPDK using the cached
build.  And probably also need a step to quick test to verify the output of
'ovs-vswitchd -V'.

We cannot use the cached dpdk version. It is a very minimal dpdk, without mlx5 pmd. Doca installation also provides the compatible dpdk (25.11 + few critical bug fixes - for advanced features that you probably won't encounter).

I added the "DOCA" prefix to the print of the doca version and check it exists in -V.


+
+    - name: build
+      run:  ./.ci/doca-build.sh
+
+    - name: upload logs on failure
+      if: failure() || cancelled()
+      uses: actions/upload-artifact@v4
+      with:
+        name: logs-doca-ubuntu-${{ matrix.compiler }}-${{ matrix.doca_link }}
+        path: config.log
diff --git a/Makefile.am b/Makefile.am
index a805f21d1..ddc3e931e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -77,6 +77,8 @@ EXTRA_DIST = \
       MAINTAINERS.rst \
       README.rst \
       NOTICE \
+     .ci/doca-build.sh \
+     .ci/doca-install.sh \
       .ci/dpdk-build.sh \
       .ci/dpdk-prepare.sh \
       .ci/linux-build.sh \
diff --git a/acinclude.m4 b/acinclude.m4
index 060c416f8..e8d475f37 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -374,6 +374,179 @@ AC_DEFUN([OVS_CHECK_LINUX_AF_XDP], [
    AM_CONDITIONAL([HAVE_AF_XDP], test "$AF_XDP_ENABLE" = true)
  ])

+dnl OVS_CHECK_DOCA
+dnl
+dnl Configure DOCA source tree
+AC_DEFUN([OVS_CHECK_DOCA], [
+  AC_ARG_WITH([doca],
+              [AS_HELP_STRING([--with-doca=static],
The code below seems to have something like; --with-doca=static|shared|<path>
should this be removed, or this help be updated?  If the latter we also need
documentation updates in the next patch.
I removed the <path> option.

To simplify things, would it be an idea to align DOCA with DPDK?
Meaning, we just add an --enable-doca option and it takes the link
mode from whatever is configured for DPDK? A quick glance on the
changes shows a lot cleaner implementation.

I agree we don't really need "mixed" linkage types.

However, I tried it. It doesn't look simpler I prefer to keep it as is.

Also, in the future we may remove the dependency with dpdk.


+                              [Specify "static" depending on the
+                              DOCA libraries to use. A custom DOCA install path
+                              can be used otherwise for local builds.])],
+              [have_doca=true])
+
+  if test "$have_dpdk" != true || test "$with_dpdk" = no; then
+    if test "$have_doca" = true; then
+      AC_MSG_ERROR([Cannot compile link against doca without dpdk, please add 
--with-dpdk])
"compile link" reads awkwardly.  Should this just be "Cannot compile with doca 
without..."?
Ack

+    fi
+  fi
+  AC_MSG_CHECKING([whether doca is enabled])
+  if test "$have_doca" != true || test "$with_doca" = no; then
+    AC_MSG_RESULT([no])
+    DOCALIB_FOUND=false
+  else
+    AC_MSG_RESULT([yes])
+    if test -d "$with_doca"; then
+      DOCA_INSTALL="$with_doca"
+    elif test -d "/opt/mellanox/doca"; then
+      DOCA_INSTALL=/opt/mellanox/doca
+    else
+      DOCA_INSTALL=/usr/local
+    fi
+    DOCA_PKGCONFIG="$(find ${DOCA_INSTALL} -type f -name doca-flow.pc -exec dirname 
{} \; | head -1)"
+    if test -n "$DOCA_PKGCONFIG"; then
+      if test -n "$PKG_CONFIG_PATH"; then
+        export PKG_CONFIG_PATH="${DOCA_PKGCONFIG}:${PKG_CONFIG_PATH}"
+      else
+        export PKG_CONFIG_PATH="${DOCA_PKGCONFIG}"
+      fi
Can we replace this inner if/else with something like this:

export 
PKG_CONFIG_PATH="${DOCA_PKGCONFIG}${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}"
Ack

+    fi
+
+    echo "checking for DOCA in PKG_CONFIG_PATH='${PKG_CONFIG_PATH}'"
We should not use echo, I think AC_MSG_CHECKING() would be appropriate here.
Ack

+    case "$with_doca" in
+      "static"|"shared")
+        DOCA_LINK="$with_doca"
+        ;;
+      *)
+        if test "$enable_shared" = yes; then
What if both --enable-shared and --enable-static is passed?
Also do we really need this third option, or should we keep it like DPDK?
Only static or shared?
Removed

+          DOCA_LINK="shared"
+        else
+          DOCA_LINK="static"
+        fi
+        ;;
+    esac
+
+    DOCA_PKGS="doca-flow doca-dpdk-bridge doca-common"
+    if test "$DOCA_LINK" = static; then
+      PKG_CHECK_MODULES_STATIC([DOCA], [$DOCA_PKGS], [],
+          [AC_MSG_ERROR([unable to use $DOCA_PKGS .pc files for $DOCA_LINK 
build])])
+    else
+      PKG_CHECK_MODULES([DOCA], [$DOCA_PKGS], [],
+          [AC_MSG_ERROR([unable to use $DOCA_PKGS .pc files for $DOCA_LINK 
build])])
+    fi
+    DOCA_INCLUDE="$DOCA_CFLAGS -DDOCA_ALLOW_EXPERIMENTAL_API"
+
+    if test "$DOCA_LINK" = static; then
+      # pkg-config --static may emit the same library in duplicate
+      # --whole-archive blocks when multiple packages share a dependency
+      # (both doca-flow and doca-dpdk-bridge pull in doca-common).
+      # Linking the same .a under --whole-archive twice causes "multiple
+      # definition" errors. Remove the second occurrence using a sed
+      # backreference, and strip redundant shared-lib flags (-l<lib>)
+      # since the static .a is already linked via --whole-archive.
For comments add a double space between sentences.
Ack

+      DOCA_DEDUP_LIBS="doca_common doca_dpdk_bridge"
+      for lib in $DOCA_DEDUP_LIBS; do
+        lib_count=$(echo "$DOCA_LIBS" | grep -o "l:lib${lib}\.a" | wc -l)
+        if test "$lib_count" -ge 2; then
+          DOCA_LIBS=$(echo "$DOCA_LIBS" | sed "s@-Wl,--whole-archive -L[[^ ]]* 
-l:lib${lib}\.a -Wl,--no-whole-archive -Wl,--as-needed @@2g")
The "Ng" form of the sed substitution flag is a GNU sed extension.
We should try to avoid this, as in theory we can build on FreeBSD.

Maybe something like this (not tested):

if test "$DOCA_LINK" = static; then
   # pkg-config --static may emit the same library in duplicate
   # --whole-archive blocks when multiple packages share a dependency
   # (both doca-flow and doca-dpdk-bridge pull in doca-common).
   # Linking the same .a under --whole-archive twice causes "multiple
   # definition" errors.  Remove duplicate occurrences, keeping only
   # the first, and strip redundant shared-lib flags (-l<lib>) since
   # the static .a is already linked via --whole-archive.
   DOCA_DEDUP_LIBS="doca_common doca_dpdk_bridge"
   for lib in $DOCA_DEDUP_LIBS; do
     DOCA_LIBS=$(echo "$DOCA_LIBS" | tr ' ' '\n' | awk '
         /l:lib'"${lib}"'\.a/ { if (seen++) next }
         { print }
     ' | tr '\n' ' ')
     if echo "$DOCA_LIBS" | grep -q "l:lib${lib}\.a"; then
       DOCA_LIBS=$(echo "$DOCA_LIBS" | sed "s/-l${lib}//g")
     fi
   done
fi
This code doesn't work. DOCA is supported only on linux. Kept as is.

+        fi
+        if echo "$DOCA_LIBS" | grep -q "l:lib${lib}\.a"; then
+          DOCA_LIBS=$(echo "$DOCA_LIBS" | sed "s/-l${lib}//g")
+        fi
+      done
+    fi
+
+    USED_PATH=`$PKG_CONFIG --variable=prefix doca-flow`
Use $() like you do everywhere else:
   USED_PATH=$($PKG_CONFIG --variable=prefix doca-flow)
Ack=

+    echo "Using DOCA release: '$USED_PATH'"
Same as above on echo use; AC_MSG_NOTICE()?
Ack

+
+    ovs_save_CFLAGS="$CFLAGS"
+    ovs_save_LDFLAGS="$LDFLAGS"
+    # Statically linked libraries might have been built with sanitizers 
enabled.
+    # In such case, use the generated sanitizer cflags.
+    CFLAGS="$CFLAGS $SANITIZER_CFLAGS $DOCA_INCLUDE"
+
+    AC_MSG_CHECKING([for doca_flow.h])
+    AC_COMPILE_IFELSE(
+      [AC_LANG_PROGRAM([#include <doca_flow.h>],
+                       [struct doca_flow_port *port = NULL ;])],
+      [AC_MSG_RESULT([yes])],
+      [AC_MSG_RESULT([no])
+       AC_MSG_ERROR(m4_normalize([
+          Unable to include doca_flow.h, check the config.log for more details.
+          As a DOCA library was found in the current search path, a missing 
doca_flow.h
+          usually means that it was built without DOCA-flow support.
+          Verify that you fullfilled all DOCA-flow build dependencies and that 
it
"fullfilled" should be "fulfilled".
Ack

+          was not automatically disabled.]))
+      ])
+
+    # DOCA's static pkg-config output already includes DPDK through
+    # its transitive dependency on libdpdk (via doca-dpdk-bridge), so
+    # no need to add DPDK_LIB separately for static link tests.
+    if test "$enable_shared" = yes; then
+      LIBS="$DOCA_LIBS $LIBS"
+    else
+      LIBS="$DOCA_LIBS $ovs_save_libs_before_dpdk"
I do not like saving the libraries in a variable and then replacing it.
Could we fix this in a cleaner way? Maybe delay adding DPDK_LIB to LIBS until
after the DOCA check? We are also resetting some other variables below.

Maybe we should split this up into something like:

     OVS_CHECK_DPDK
     OVS_CHECK_DOCA
     OVS_CHECK_DPDK_POST_DOCA

Not sure if this would be accepted, but it might make things a bit
cleaner.

I think it will be even less clear. Hopefully if we move to meson based compilation and stop using pkg-config it will simplify things a lot.

For now, this is the way it is.


+    fi
+    AC_MSG_CHECKING([for DOCA-flow link])
+    AC_LINK_IFELSE(
+      [AC_LANG_PROGRAM([#include <doca_flow_net.h>
+                        #include <doca_flow.h>],
+                       [struct doca_flow_cfg *cfg;
+                        int rv;
+                        doca_flow_cfg_create(&cfg);
+                        rv = doca_flow_init(cfg);
+                        doca_flow_cfg_destroy(cfg);
+                        return rv;])],
+      [AC_MSG_RESULT([yes])
+        DOCALIB_FOUND=true],
+      [AC_MSG_RESULT([no])
+        AC_MSG_ERROR(m4_normalize([
+           Unable to link with DOCA-flow, check the config.log for more 
details.
+           If a working DOCA-flow library was not found in the current search 
path,
+           update PKG_CONFIG_PATH for pkg-config to find the .pc file in a 
proper location.]))
+      ])
+    CFLAGS="$ovs_save_CFLAGS"
+    LDFLAGS="$ovs_save_LDFLAGS"
+    OVS_CFLAGS="$OVS_CFLAGS $DOCA_INCLUDE -Wno-deprecated-declarations 
-DALLOW_EXPERIMENTAL_API"
Why do we add -Wno-deprecated-declarations?  Should we not see these warnings?
Removed

Also, enabling experimental DPDK APIs globally with -DALLOW_EXPERIMENTAL_API
is not desirable.  There are plans to remove experimental APIs completely.
Which specific DPDK APIs require this flag?  It might be better to get those
promoted out of experimental state instead.

We must have ALLOW_EXPERIMENTAL_API. For example rte_pmd_mlx5_enable_steering().

If all APIs we use become non-experimental we will be able to remove it. For now we can't.


+
+    # DOCA libraries are very specific in their ordering and inherit DPDK
...
  lib_libopenvswitch_la_SOURCES += \
       lib/dpif-netlink.c \
diff --git a/lib/dpdk.h b/lib/dpdk.h
index 1b790e682..7571604dd 100644
--- a/lib/dpdk.h
+++ b/lib/dpdk.h
@@ -18,6 +18,7 @@
  #define DPDK_H

  #include <stdbool.h>
+#include <stdint.h>
Any reason why we needed this addition?
Removed

  #ifdef DPDK_NETDEV

diff --git a/lib/ovs-doca.c b/lib/ovs-doca.c
new file mode 100644
index 000000000..eae361a21
--- /dev/null
+++ b/lib/ovs-doca.c
@@ -0,0 +1,86 @@
+/*
+ * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES.
+ * All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
The license header in ovs-doca.c and ovs-doca.h should use the
standard OVS format, without SPDX tags (same for previous patches
in this series). Please use only the copyright line and the plain
Apache 2.0 license text, as seen in the rest of the codebase.
Ack. in all new files.

+
+#include <config.h>
Own include should be first, see earlier comment. So:

#include <config.h>

#include "ovs-doca.h"

#include "compiler.h"
#include "vswitch-idl.h"
Ack. in all new files.

+
+#include "compiler.h"
+#include "ovs-doca.h"
+#include "vswitch-idl.h"
+
+#ifdef DOCA_NETDEV
+
+#include <rte_common.h>
+#include <rte_pmd_mlx5.h>
+
+#include <doca_version.h>
+
+/* DOCA disables dpdk steering as a constructor in higher priority.
+ * Set a lower priority one to enable it back. Disable it only upon using
Two spaces between sentences.
Ack

+ * doca ports.
+ */
For new files we should try to end multi line comments on the same line. So;

   * doca ports. */


But in general the comment is a little hard to follow. "Disable it only
upon using doca ports" appears to be a note about future intent rather
than a description of what this code does.  Can it be reworded to be
self-contained, e.g. explaining that DOCA installs a higher-priority
constructor that disables DPDK steering, and that this lower-priority
constructor re-enables it?
Rephrased.

+RTE_INIT(dpdk_steering_enable)
+{
+    rte_pmd_mlx5_enable_steering();
+}
...
+
+#ifndef OVS_DOCA_H
+#define OVS_DOCA_H
+
+#include <config.h>
This include should not be needed.

Ack

...

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to