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

Note that the value selected for doca must be the same as selected for
dpdk.

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                    |  53 ++++++++
 .ci/doca-install.sh                  |  19 +++
 .ci/dpdk-build.sh                    |   5 +-
 .github/workflows/build-and-test.yml |  92 +++++++++++++-
 Makefile.am                          |   2 +
 acinclude.m4                         | 175 +++++++++++++++++++++++++++
 configure.ac                         |   1 +
 lib/automake.mk                      |   2 +
 lib/ovs-doca.c                       |  83 +++++++++++++
 lib/ovs-doca.h                       |  27 +++++
 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, 480 insertions(+), 7 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..d48ea9ef8
--- /dev/null
+++ b/.ci/doca-build.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+set -o errexit
+set -x
+
+CFLAGS_FOR_OVS="-g -O2"
+EXTRA_OPTS="--enable-Werror"
+JOBS=${JOBS:-"-j4"}
+
+DOCA_LINK="${DOCA_LINK:-static}"
+
+# DOCA .pc directory.
+DOCA_PKGCONFIG=$(find /opt/mellanox/doca -name pkgconfig -type d 2>/dev/null \
+                 | head -1)
+
+DPDK_INSTALL_DIR="${DPDK_INSTALL_DIR:-$(pwd)/dpdk-dir}"
+DPDK_VERSION_FILE="${DPDK_INSTALL_DIR}/cached-version"
+if [ -f "${DPDK_VERSION_FILE}" ]; then
+    DPDK_LIB=${DPDK_INSTALL_DIR}/lib/x86_64-linux-gnu
+    dpdk_pc="${DPDK_LIB}/pkgconfig:${DOCA_PKGCONFIG}"
+    cfg_tail="${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}"
+    export PKG_CONFIG_PATH="${dpdk_pc}${cfg_tail}"
+    export PATH="${DPDK_INSTALL_DIR}/bin:${PATH}"
+    dv=$(cat "${DPDK_VERSION_FILE}")
+    echo "Using cached DPDK ${dv} from ${DPDK_INSTALL_DIR}"
+else
+    cfg_tail="${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}"
+    export PKG_CONFIG_PATH="${DOCA_PKGCONFIG}${cfg_tail}"
+    DPDK_LIB=""
+fi
+
+if [ "$DOCA_LINK" = "shared" ]; then
+    DOCA_LIB=${DOCA_PKGCONFIG%/pkgconfig}
+    prefix="${DPDK_LIB:+$DPDK_LIB:}${DOCA_LIB}"
+    export LD_LIBRARY_PATH="${prefix}:${LD_LIBRARY_PATH:-}"
+fi
+sudo ldconfig
+
+EXTRA_OPTS="$EXTRA_OPTS --with-dpdk=$DOCA_LINK --with-doca=$DOCA_LINK"
+
+./boot.sh
+./configure CFLAGS="${CFLAGS_FOR_OVS}" $EXTRA_OPTS
+make $JOBS
+
+if ! vswitchd/ovs-vswitchd -V 2>&1 | grep -q 'DOCA'; then
+    echo "Expected 'DOCA' in ovs-vswitchd -V output for DOCA build." >&2
+    vswitchd/ovs-vswitchd -V || true
+    exit 1
+fi
+
+export DISTCHECK_CONFIGURE_FLAGS="$EXTRA_OPTS"
+make distcheck ${JOBS} CFLAGS="${CFLAGS_FOR_OVS}" \
+    TESTSUITEFLAGS="${JOBS} ${TEST_RANGE}" RECHECK=yes
diff --git a/.ci/doca-install.sh b/.ci/doca-install.sh
new file mode 100755
index 000000000..8e78cd8b1
--- /dev/null
+++ b/.ci/doca-install.sh
@@ -0,0 +1,19 @@
+#!/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 libdoca-sdk-flow-dev libdoca-sdk-dpdk-bridge-dev
+
diff --git a/.ci/dpdk-build.sh b/.ci/dpdk-build.sh
index 991b272ea..5bf1a1296 100755
--- a/.ci/dpdk-build.sh
+++ b/.ci/dpdk-build.sh
@@ -38,9 +38,12 @@ function build_dpdk()
 
     # OVS compilation and "normal" unit tests (run in the CI) do not depend on
     # any DPDK driver.
-    # check-dpdk unit tests requires testpmd and some net/ driver.
+    # check-dpdk unit tests require testpmd and some net/ driver.
     DPDK_OPTS="$DPDK_OPTS -Denable_apps=test-pmd"
     enable_drivers="net/null,net/af_xdp,net/tap,net/virtio"
+    # For DOCA mlx5 driver is also required. net/mlx5 pulls in common/mlx5
+    # which requires bus/auxiliary.
+    enable_drivers+=",bus/auxiliary,common/mlx5,net/mlx5,net/null"
     DPDK_OPTS="$DPDK_OPTS -Denable_drivers=$enable_drivers"
     # OVS depends on the vhost library (and its dependencies).
     # net/tap depends on the gso library.
diff --git a/.github/workflows/build-and-test.yml 
b/.github/workflows/build-and-test.yml
index f3d490156..0c30422a0 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -11,7 +11,9 @@ jobs:
       matrix:
         runner: [ubuntu-24.04]
     env:
-      dependencies: gcc libnuma-dev libxdp-dev ninja-build pkgconf
+      dependencies: >
+        gcc libnuma-dev libbpf-dev libxdp-dev ninja-build pkgconf
+        libibverbs-dev rdma-core
       CC: gcc
       DPDK_GIT: https://dpdk.org/git/dpdk-stable
       DPDK_VER: 25.11
@@ -66,6 +68,7 @@ jobs:
     - name: update APT cache
       if: steps.dpdk_cache.outputs.cache-hit != 'true'
       run:  sudo apt update || true
+
     - name: install common dependencies
       if: steps.dpdk_cache.outputs.cache-hit != 'true'
       run:  sudo apt install -y ${{ env.dependencies }}
@@ -137,7 +140,8 @@ jobs:
     env:
       dependencies: |
         automake libtool gcc bc libjemalloc2 libjemalloc-dev libssl-dev \
-        llvm-dev libnuma-dev selinux-policy-dev libxdp-dev lftp
+        llvm-dev libnuma-dev selinux-policy-dev libibverbs-dev rdma-core \
+        libbpf-dev libxdp-dev lftp
       CC:          ${{ matrix.compiler }}
       DPDK:        ${{ matrix.dpdk }}
       DPDK_SHARED: ${{ matrix.dpdk_shared }}
@@ -358,7 +362,7 @@ jobs:
     env:
       dependencies: |
         automake bc clang-tools libnuma-dev libunbound-dev libunwind-dev \
-        libssl-dev libtool libxdp-dev llvm-dev
+        libssl-dev libtool libibverbs-dev rdma-core libbpf-dev libxdp-dev 
llvm-dev
       CC:   clang
       DPDK: dpdk
       CLANG_ANALYZE: true
@@ -474,7 +478,7 @@ jobs:
     env:
       dependencies: |
         automake bc clang-tools libnuma-dev libunbound-dev libunwind-dev \
-        libssl-dev libtool libxdp-dev llvm-dev
+        libssl-dev libtool libibverbs-dev rdma-core libbpf-dev libxdp-dev 
llvm-dev
       CC:   clang
       DPDK: dpdk
       CLANG_ANALYZE: true
@@ -703,3 +707,83 @@ jobs:
         path: |
           rpm/rpmbuild/SRPMS/*.rpm
           rpm/rpmbuild/RPMS/*/*.rpm
+
+  build-doca:
+    needs: [build-dpdk]
+    env:
+      dependencies: |
+        automake libtool gcc bc libssl-dev llvm-dev libnuma-dev \
+        libunbound-dev libunwind-dev libsystemd-dev wget python3-pip \
+        libibverbs-dev rdma-core libbpf-dev libxdp-dev pkgconf
+      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
+    - name: install common dependencies
+      run:  sudo apt install -y ${{ env.dependencies }}
+
+    - name: get cached dpdk-dir
+      uses: actions/cache/restore@v5
+      with:
+        path: dpdk-dir
+        key: ${{ needs.build-dpdk.outputs.dpdk_key }}
+        fail-on-cache-miss: true
+
+    - name: install DOCA
+      run:  ./.ci/doca-install.sh
+
+    - name: build
+      run:  ./.ci/doca-build.sh
+
+    - name: copy logs on failure
+      if: failure() || cancelled()
+      run: |
+        # upload-artifact throws exceptions if it tries to upload socket
+        # files and we could have some socket files in testsuite.dir.
+        # Also, upload-artifact doesn't work well enough with wildcards.
+        # So, we're just archiving everything here to avoid any issues.
+        mkdir logs
+        cp config.log ./logs/
+        cp -r ./*/_build/sub/tests/testsuite.* ./logs/ || true
+        sudo cp -r ./tests/*testsuite.* ./logs/ || true
+        sudo tar -czvf logs.tgz logs/
+
+    - name: upload logs on failure
+      if: failure() || cancelled()
+      uses: actions/upload-artifact@v7
+      with:
+        name: logs-doca-ubuntu-${{ matrix.compiler }}-${{ matrix.doca_link }}
+        path: logs.tgz
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 54d7c3e0e..35ce07d7a 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -374,6 +374,177 @@ 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|shared|yes],
+                              [Specify "static"/"yes" or "shared" depending
+                              on the DOCA libraries to use.
+                              Requires --with-dpdk to be set the same.])],
+              [], [])
+
+  DOCA_LINK=
+    case "$with_doca" in
+      "shared")
+          DOCA_LINK=shared
+          ;;
+      "static" | "yes")
+          DOCA_LINK=static
+          ;;
+    esac
+
+  if test -n "$DOCA_LINK"; then
+    if test "$DOCA_LINK" != "$DPDK_LINK"; then
+      AC_MSG_ERROR(m4_normalize([DOCA requires --with-doca and --with-dpdk to 
be the same.]))
+    fi
+  fi
+
+  AC_MSG_CHECKING([whether doca is enabled])
+  if test -z "$DOCA_LINK"; then
+    AC_MSG_RESULT([no])
+    DOCALIB_FOUND=false
+  else
+    AC_MSG_RESULT([yes])
+
+    DOCA_PKGCONFIG="$(find /opt/mellanox/doca -type f -name doca-flow.pc -exec 
dirname {} \; | head -1)"
+    export 
PKG_CONFIG_PATH="$PKG_CONFIG_PATH${DOCA_PKGCONFIG:+${PKG_CONFIG_PATH:+:}}$DOCA_PKGCONFIG"
+
+    AC_MSG_CHECKING([for DOCA in PKG_CONFIG_PATH='${PKG_CONFIG_PATH}'])
+
+    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.
+      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")
+        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
+
+    # Strip DPDK from DOCA_LIBS; it is covered by 
DPDK_LIB/DPDK_vswitchd_LDFLAGS.
+    DOCA_LIBS=$(echo "$DOCA_LIBS" | sed 's/-l:librte_[[^ ]]*\.a//g; 
s/-lrte_[[^ ]]*//g; s@-L[[^ ]]*/dpdk[[^ ]]*/lib[[^ ]]*@@g' | sed 's/  */ /g; 
s/-Wl,--whole-archive  *-Wl,--no-whole-archive//g; s/^ *//; s/ *$//')
+
+    # For shared builds, ensure doca_common is included (may only be
+    # in Requires.private and not in Libs field of .pc files).
+    if test "$DOCA_LINK" = shared; then
+      if ! echo "$DOCA_LIBS" | grep -q "\-ldoca_common"; then
+        DOCA_LIBS="$DOCA_LIBS -ldoca_common"
+      fi
+    fi
+
+    USED_PATH=$($PKG_CONFIG --variable=prefix doca-flow)
+    AC_MSG_NOTICE([Using DOCA release: '$USED_PATH'])
+
+    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 fulfilled all DOCA-flow build dependencies and that 
it
+          was not automatically disabled.]))
+      ])
+
+    # DPDK was stripped from DOCA_LIBS above; add DPDK_LIB for the link test.
+    if test "$DOCA_LINK" = static; then
+      LIBS="$DOCA_LIBS $DPDK_LIB $ovs_save_libs_before_dpdk"
+    else
+      LIBS="$DOCA_LIBS $ovs_save_libs_before_dpdk"
+    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"
+    # Keep bare DOCA libs (no --whole-archive) in LIBS; OVS_LDFLAGS covers the 
rest.
+    if test "$DOCA_LINK" = static; then
+      doca_libs_no_wa=$(echo "$DOCA_LIBS" | sed 's/ *-Wl,--whole-archive//g; 
s/ *-Wl,--no-whole-archive//g')
+      LIBS="$doca_libs_no_wa $ovs_save_libs_before_dpdk"
+    fi
+    OVS_CFLAGS="$OVS_CFLAGS $DOCA_INCLUDE -DALLOW_EXPERIMENTAL_API"
+
+    # DOCA libraries are very specific in their ordering and inherit DPDK
+    # libraries which contain --whole-archive.  Autotools will reorder
+    # them, breaking static links.  Use the same solution as DPDK below.
+    # Transform the pkg-config output into a single linker parameter, separated
+    # by commas and wrapped by -Wl.
+    DOCA_LDFLAGS=$(echo "$DOCA_LIBS" | tr -s ' ' ',' | sed 's/-Wl,//g')
+    # Replace -pthread with -lpthread for LD and remove the last extra comma.
+    DOCA_LDFLAGS=$(echo "$DOCA_LDFLAGS"| sed 's/,$//' | sed 
's/-pthread/-lpthread/g')
+    # Prepend "-Wl,".
+    DOCA_LDFLAGS="-Wl,$DOCA_LDFLAGS"
+
+    # The full DOCA linker parameters must be made available to every
+    # object trying to link against libopenvswitch.  It means every
+    # binary generated will contain DOCA unfortunately.
+    if test "$DOCA_LINK" = static; then
+      OVS_LDFLAGS="$OVS_LDFLAGS $DOCA_LDFLAGS $DPDK_vswitchd_LDFLAGS"
+      # Clear to prevent double linkage from Makefile.am.
+      DPDK_vswitchd_LDFLAGS=""
+    else
+      # For shared builds, DPDK is not in DOCA's output (libdpdk is in
+      # Requires.private, not followed by pkg-config without --static).
+      # Link DPDK separately.  Add mlx5 PMD explicitly as it may
+      # not be in Libs field for shared builds.
+      if ! echo "$DPDK_LIB" | grep -q "\-lrte_net_mlx5"; then
+        DPDK_LIB="$DPDK_LIB -lrte_net_mlx5"
+      fi
+      OVS_LDFLAGS="$OVS_LDFLAGS $DOCA_LDFLAGS $DPDK_LIB"
+    fi
+    AC_DEFINE([DOCA_NETDEV], [1], [System uses the DOCA module.])
+  fi
+
+  AM_CONDITIONAL([DOCA_NETDEV], [$DOCALIB_FOUND])
+])
+
 dnl OVS_CHECK_DPDK
 dnl
 dnl Configure DPDK source tree
@@ -388,15 +559,18 @@ AC_DEFUN([OVS_CHECK_DPDK], [
   if test "$have_dpdk" != true || test "$with_dpdk" = no; then
     AC_MSG_RESULT([no])
     DPDKLIB_FOUND=false
+    DPDK_LINK=
   else
     AC_MSG_RESULT([yes])
     case "$with_dpdk" in
       "shared")
+          DPDK_LINK=shared
           PKG_CHECK_MODULES([DPDK], [libdpdk], [
               DPDK_INCLUDE="$DPDK_CFLAGS"
               DPDK_LIB="$DPDK_LIBS"])
               ;;
       "static" | "yes")
+          DPDK_LINK=static
           PKG_CHECK_MODULES_STATIC([DPDK], [libdpdk], [
               DPDK_INCLUDE="$DPDK_CFLAGS"
               DPDK_LIB="$DPDK_LIBS"])
@@ -478,6 +652,7 @@ AC_DEFUN([OVS_CHECK_DPDK], [
     OVS_FIND_DEPENDENCY([dlopen], [dl], [libdl])
 
     AC_MSG_CHECKING([whether linking with dpdk works])
+    ovs_save_libs_before_dpdk="$LIBS"
     LIBS="$DPDK_LIB $LIBS"
     AC_LINK_IFELSE(
       [AC_LANG_PROGRAM([#include <rte_config.h>
diff --git a/configure.ac b/configure.ac
index 2a488600a..780850a80 100644
--- a/configure.ac
+++ b/configure.ac
@@ -205,6 +205,7 @@ OVS_CHECK_LINUX_TC
 OVS_CHECK_LINUX_SCTP_CT
 OVS_CHECK_LINUX_VIRTIO_TYPES
 OVS_CHECK_DPDK
+OVS_CHECK_DOCA
 OVS_CHECK_PRAGMA_MESSAGE
 OVS_CHECK_VERSION_SUFFIX
 AC_SUBST([CFLAGS])
diff --git a/lib/automake.mk b/lib/automake.mk
index bab03c3e7..c3a1b603a 100644
--- a/lib/automake.mk
+++ b/lib/automake.mk
@@ -270,6 +270,8 @@ lib_libopenvswitch_la_SOURCES = \
        lib/ovs-atomic-pthreads.h \
        lib/ovs-atomic-x86_64.h \
        lib/ovs-atomic.h \
+       lib/ovs-doca.c \
+       lib/ovs-doca.h \
        lib/ovs-lldp.c \
        lib/ovs-lldp.h \
        lib/ovs-numa.c \
diff --git a/lib/ovs-doca.c b/lib/ovs-doca.c
new file mode 100644
index 000000000..4571f8cf2
--- /dev/null
+++ b/lib/ovs-doca.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <config.h>
+
+#include "ovs-doca.h"
+
+#include "compiler.h"
+#include "vswitch-idl.h"
+
+#ifdef DOCA_NETDEV
+
+#include <rte_common.h>
+#include <rte_pmd_mlx5.h>
+
+#include <doca_version.h>
+
+/* DOCA installs a higher-priority constructor that disables DPDK steering.
+ * This lower-priority constructor re-enables it. */
+RTE_INIT(dpdk_steering_enable)
+{
+    rte_pmd_mlx5_enable_steering();
+}
+
+void
+ovs_doca_init(const struct smap *ovs_other_config OVS_UNUSED)
+{
+}
+
+void
+print_doca_version(void)
+{
+    printf("DOCA %s\n", doca_version_runtime());
+}
+
+void
+ovs_doca_status(const struct ovsrec_open_vswitch *cfg)
+{
+    if (!cfg) {
+        return;
+    }
+
+    ovsrec_open_vswitch_set_doca_initialized(cfg, false);
+    ovsrec_open_vswitch_set_doca_version(cfg, doca_version_runtime());
+}
+
+#else /* DOCA_NETDEV */
+
+void
+ovs_doca_init(const struct smap *ovs_other_config OVS_UNUSED)
+{
+}
+
+void
+print_doca_version(void)
+{
+}
+
+void
+ovs_doca_status(const struct ovsrec_open_vswitch *cfg)
+{
+    if (!cfg) {
+        return;
+    }
+
+    ovsrec_open_vswitch_set_doca_initialized(cfg, false);
+    ovsrec_open_vswitch_set_doca_version(cfg, "none");
+}
+
+#endif /* DOCA_NETDEV */
diff --git a/lib/ovs-doca.h b/lib/ovs-doca.h
new file mode 100644
index 000000000..369424cc3
--- /dev/null
+++ b/lib/ovs-doca.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef OVS_DOCA_H
+#define OVS_DOCA_H
+
+#include "smap.h"
+#include "vswitch-idl.h"
+
+void ovs_doca_init(const struct smap *ovs_other_config);
+void print_doca_version(void);
+void ovs_doca_status(const struct ovsrec_open_vswitch *);
+
+#endif /* OVS_DOCA_H */
diff --git a/utilities/checkpatch_dict.txt b/utilities/checkpatch_dict.txt
index 5ad599c1d..6a454bcf8 100644
--- a/utilities/checkpatch_dict.txt
+++ b/utilities/checkpatch_dict.txt
@@ -55,6 +55,7 @@ dhcpv4
 dhcpv6
 dnat
 dns
+doca
 dpcls
 dpctl
 dpdk
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 7a68e19ac..dd494b0f6 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -50,6 +50,7 @@
 #include "openvswitch/ofpbuf.h"
 #include "openvswitch/vconn.h"
 #include "openvswitch/vlog.h"
+#include "ovs-doca.h"
 #include "ovs-lldp.h"
 #include "ovs-numa.h"
 #include "packets.h"
@@ -451,6 +452,8 @@ bridge_init(const char *remote)
     ovsdb_idl_omit(idl, &ovsrec_open_vswitch_col_system_version);
     ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_dpdk_version);
     ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_dpdk_initialized);
+    ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_doca_version);
+    ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_doca_initialized);
 
     ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_datapath_id);
     ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_datapath_version);
@@ -3260,6 +3263,7 @@ run_status_update(void)
             connectivity_seqno = seq;
             status_txn = ovsdb_idl_txn_create(idl);
             dpdk_status(cfg);
+            ovs_doca_status(cfg);
             HMAP_FOR_EACH (br, node, &all_bridges) {
                 struct port *port;
 
@@ -3400,6 +3404,7 @@ bridge_run(void)
 
     if (cfg) {
         dpdk_init(&cfg->other_config);
+        ovs_doca_init(&cfg->other_config);
         userspace_tso_init(&cfg->other_config);
     }
 
diff --git a/vswitchd/ovs-vswitchd.c b/vswitchd/ovs-vswitchd.c
index 6d90c73b8..03c739443 100644
--- a/vswitchd/ovs-vswitchd.c
+++ b/vswitchd/ovs-vswitchd.c
@@ -30,6 +30,7 @@
 #include "compiler.h"
 #include "daemon.h"
 #include "dirs.h"
+#include "dpdk.h"
 #include "dpif.h"
 #include "dummy.h"
 #include "fatal-signal.h"
@@ -37,6 +38,7 @@
 #include "netdev.h"
 #include "openflow/openflow.h"
 #include "ovsdb-idl.h"
+#include "ovs-doca.h"
 #include "ovs-rcu.h"
 #include "ovs-router.h"
 #include "ovs-thread.h"
@@ -220,6 +222,7 @@ parse_options(int argc, char *argv[], char **unixctl_pathp)
         case 'V':
             ovs_print_version(0, 0);
             print_dpdk_version();
+            print_doca_version();
             exit(EXIT_SUCCESS);
 
         case OPT_MLOCKALL:
diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema
index c658291c7..d3b84ac30 100644
--- a/vswitchd/vswitch.ovsschema
+++ b/vswitchd/vswitch.ovsschema
@@ -1,6 +1,6 @@
 {"name": "Open_vSwitch",
- "version": "8.8.0",
- "cksum": "2823623553 27869",
+ "version": "8.9.0",
+ "cksum": "2639123554 28037",
  "tables": {
    "Open_vSwitch": {
      "columns": {
@@ -56,6 +56,11 @@
        "dpdk_initialized": {
          "type": "boolean"},
        "dpdk_version": {
+         "type": {"key": {"type": "string"},
+                  "min": 0, "max": 1}},
+       "doca_initialized": {
+         "type": "boolean"},
+       "doca_version": {
          "type": {"key": {"type": "string"},
                   "min": 0, "max": 1}}},
      "isRoot": true,
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index d8c26e4da..4bd694136 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -972,6 +972,10 @@
         true and the DPDK library is successfully initialized.
       </column>
 
+      <column name="doca_initialized">
+        Always false.
+      </column>
+
       <group title="Statistics">
         <p>
           The <code>statistics</code> column contains key-value pairs that
@@ -1156,6 +1160,12 @@
         </p>
       </column>
 
+      <column name="doca_version">
+        <p>
+          The version of the linked DOCA library.
+        </p>
+      </column>
+
     </group>
 
     <group title="Capabilities">
-- 
2.34.1

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

Reply via email to