Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 33 additions & 7 deletions install-external-deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,21 @@ install_pfring_zc_build_deps() {
#
# Set ANYSCAN_INSTALL_DPDK_DEPS=false to suppress this block (e.g. on
# AMIs where the operator pre-pinned a different libdpdk version).
# Per-NIC DPDK PMD packages. Debian DPDK 24.11.x ships every Poll-Mode
# Driver as its own package (librte-net-<vendor><abi>) instead of shoving
# them all into libdpdk-dev. Without the relevant PMD installed,
# rte_eal_init() succeeds but no eth ports are probed and the scanner
# refuses to start (anygpt-52 hit this on c6in.metal: ENA NICs silently
# absent from rte_eth_dev_count_avail() until librte-net-ena25 was
# apt-installed manually).
#
# We pull both the AWS PMD (ENA — every c6in/c5n/m5n/m6in instance) and
# the Mellanox PMD (mlx5 — bare-metal hosts at Equinix/OVH/Hetzner with
# CX-5/CX-6 NICs). Stock Intel ixgbe/i40e drivers are still in
# libdpdk-dev's auto-pull set so we don't need to name them. The 25 ABI
# suffix matches Debian trixie's DPDK 24.11.x (libdpdk-dev → librte-*-25).
DPDK_PMD_PACKAGES=(librte-net-ena25 librte-net-mlx5-25)

install_dpdk_build_deps() {
if [ "${ANYSCAN_INSTALL_DPDK_DEPS:-true}" != "true" ]; then
return 0
Expand All @@ -499,21 +514,32 @@ install_dpdk_build_deps() {
else
printf '[*] Skipping DPDK build deps: not root and sudo is not available.\n'
printf ' Install manually if you plan to build the scanner with USE_DPDK=1:\n'
printf ' sudo apt-get install -y libdpdk-dev dpdk\n'
printf ' sudo apt-get install -y libdpdk-dev dpdk %s\n' "${DPDK_PMD_PACKAGES[*]}"
return 0
fi
if [ "${apt_cmd[0]}" = "sudo" ] && ! sudo -n true >/dev/null 2>&1; then
printf '[*] Skipping DPDK build deps: sudo would prompt for a password.\n'
printf ' Install manually if you plan to build the scanner with USE_DPDK=1:\n'
printf ' sudo apt-get install -y libdpdk-dev dpdk\n'
printf ' sudo apt-get install -y libdpdk-dev dpdk %s\n' "${DPDK_PMD_PACKAGES[*]}"
return 0
fi
printf '[*] Installing DPDK build deps (libdpdk-dev dpdk)...\n'
printf '[*] Installing DPDK build deps (libdpdk-dev dpdk %s)...\n' "${DPDK_PMD_PACKAGES[*]}"
if ! "${apt_cmd[@]}" install -y --no-install-recommends \
libdpdk-dev dpdk >/dev/null 2>&1; then
printf '[!] apt-get install of DPDK build deps failed; the scanner will still build with default `make`.\n' >&2
printf ' Re-run with USE_DPDK=1 only after libdpdk-dev is present.\n' >&2
return 0
libdpdk-dev dpdk "${DPDK_PMD_PACKAGES[@]}" >/dev/null 2>&1; then
# Fall back to libdpdk-dev alone if PMD packages are unavailable
# in the current archive — better to ship a partial DPDK build
# than fail the whole install. The scanner will still link
# against librte_eal but rte_eth_dev_count_avail() will return
# 0 on hosts whose NIC PMD is missing.
printf '[!] apt-get install of DPDK build deps incl. PMDs failed; retrying without PMDs.\n' >&2
if ! "${apt_cmd[@]}" install -y --no-install-recommends \
libdpdk-dev dpdk >/dev/null 2>&1; then
printf '[!] apt-get install of DPDK build deps failed; the scanner will still build with default `make`.\n' >&2
printf ' Re-run with USE_DPDK=1 only after libdpdk-dev is present.\n' >&2
return 0
fi
printf '[!] DPDK PMD packages (%s) not installed; rte_eth_dev_count_avail() may return 0 at runtime on ENA/mlx5 hosts.\n' "${DPDK_PMD_PACKAGES[*]}" >&2
printf ' Install manually once available: sudo apt-get install -y %s\n' "${DPDK_PMD_PACKAGES[*]}" >&2
fi
}

Expand Down
85 changes: 85 additions & 0 deletions tools/test-install-external-deps-dpdk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,91 @@ else
note_fail "dpdk cached-binary path" "install-external-deps.sh exited non-zero (see $case_dir/stderr.log)"
fi

# ---------------------------------------------------------------------------
# Case 5: ANYSCAN_INSTALL_DPDK_DEPS=true → apt-get install includes the
# per-NIC PMD packages (librte-net-ena25 + librte-net-mlx5-25).
#
# Without these, rte_eal_init() succeeds but rte_eth_dev_count_avail()
# returns 0 on ENA hosts (anygpt-52 hit this on c6in.metal: librte-net-
# ena25 had to be apt-installed manually before the scanner could see
# any eth ports). PR #65 issuecomment-4339242358.
# ---------------------------------------------------------------------------
case_dir="$WORK_ROOT/case-dpdk-pmd-install"
mkdir -p "$case_dir"

repo_dir="$case_dir/engine"
runtime_env="$case_dir/runtime.env"
artifact_dir="$case_dir/artifacts"
make_log="$case_dir/make.log"
git_log="$case_dir/git.log"
apt_log="$case_dir/apt.log"
stub_dir="$case_dir/stubs"
linkage_marker="$case_dir/linkage-marker"

mkdir -p "$repo_dir" "$artifact_dir"
: >"$linkage_marker" # advertise DPDK linkage so make stub produces a librte-linked scanner
: >"$repo_dir/Makefile"

prepare_stubs "$stub_dir" "$make_log" "$git_log" "$linkage_marker"

# Stub `id` so install_dpdk_build_deps takes the root branch (apt-get
# directly, not sudo). The script captures id's output via $(id -u …),
# so the stub must echo "0" not "1".
cat >"$stub_dir/id" <<'EOF'
#!/usr/bin/env bash
case "$1" in
-u) printf '0\n' ;;
*) printf '0\n' ;;
esac
EOF
chmod +x "$stub_dir/id"

# Stub `apt-get` to record argv and succeed.
cat >"$stub_dir/apt-get" <<EOF
#!/usr/bin/env bash
printf '%s\n' "\$*" >>"$apt_log"
exit 0
EOF
chmod +x "$stub_dir/apt-get"

(
export PATH="$stub_dir:$PATH"
export ANYSCAN_USE_DPDK=1
export ANYSCAN_VULNSCANNER_REPO_DIR="$repo_dir"
# Leave ANYSCAN_INSTALL_DPDK_DEPS unset (defaults to true) so
# install_dpdk_build_deps actually runs the apt-get path.
export ANYSCAN_INSTALL_AFXDP_DEPS=false
export ANYSCAN_INSTALL_PFRING_ZC_DEPS=false
export ANYSCAN_RUNTIME_ENV_FILE="$runtime_env"
export ANYSCAN_LOCAL_BOOTSTRAP_ARTIFACT_DIR="$artifact_dir"
unset SUDO_USER
"$TARGET_SCRIPT" >"$case_dir/stdout.log" 2>"$case_dir/stderr.log"
) || note_fail "dpdk pmd install path" \
"install-external-deps.sh exited non-zero (see $case_dir/stderr.log)"

if [ -s "$apt_log" ]; then
note_pass "dpdk pmd install path invokes apt-get"
assert_contains_substring \
"dpdk pmd install passes libdpdk-dev to apt-get" \
"libdpdk-dev" \
"$apt_log"
assert_contains_substring \
"dpdk pmd install passes librte-net-ena25 to apt-get (ENA PMD for AWS c6in/c5n/m6in)" \
"librte-net-ena25" \
"$apt_log"
assert_contains_substring \
"dpdk pmd install passes librte-net-mlx5-25 to apt-get (mlx5 PMD for non-AWS bare metal)" \
"librte-net-mlx5-25" \
"$apt_log"
else
note_fail "dpdk pmd install path invokes apt-get" \
"expected apt-get to be invoked but $apt_log is empty"
if [ -f "$case_dir/stderr.log" ]; then
printf ' stderr:\n' >&2
sed 's/^/ /' "$case_dir/stderr.log" >&2
fi
fi

printf '\n'
printf 'PASS: %d\n' "$PASS"
printf 'FAIL: %d\n' "$FAIL"
Expand Down