Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
972b305
lldpad eloop select change to poll
huyizhen Mar 24, 2025
b5f676b
tests: Add a new test harness based on pytest for integration.
apconole Aug 14, 2026
a9a71f4
test: Add existing legacy cases.
apconole Aug 14, 2026
e5e0957
test: Include lldp compliance tests.
apconole Aug 14, 2026
c83c214
Makefile.am: Correct a dependency issue.
apconole Aug 14, 2026
367b718
github-actions: Introduce new jobs.
apconole Aug 14, 2026
19a3425
test: Fix the QBG and VDP test utils.
apconole Aug 14, 2026
32e7bdd
ci: Switch to using 'sudo' rather than userns.
apconole Aug 14, 2026
28d0b40
gcc: Advance supported versions and drop unsupported versions.
apconole Aug 14, 2026
1acd1a0
qbg22sim: Fix dangling pointer usage.
apconole Aug 15, 2026
c41cb93
rx: Fix heap-buffer-overflow reading TLV header past frame end
apconole Aug 15, 2026
9f41350
eloop: Bound socket dispatch by the polled fds array size
apconole Aug 15, 2026
432327a
vdpnl: Fix off-by-one maxtype passed to nla_parse()
apconole Aug 15, 2026
b86ce10
test: Fix missing-End-TLV test to expect the correct rejection message
apconole Aug 15, 2026
7ba9bce
test: Detach netns mount namespaces from host propagation
apconole Aug 15, 2026
482d15b
lldp_dcbx_nl: Remove unused loop counter 'i'
apconole Aug 15, 2026
c23b4fd
lldp_dcbx_cmds: Remove unused event_flag accumulator
apconole Aug 15, 2026
c26607f
lldp_8021qaz: Remove unused loop counter 'i'
apconole Aug 15, 2026
7e1a591
vdp22: Fix stringop-truncation / OOB read risk in mgrid2str()
apconole Aug 15, 2026
5035bd3
lldp: Tolerate multiple management address TLVs
thwalsh Jul 25, 2026
57eed92
test: Add regression coverage for multiple management address TLVs
apconole Aug 15, 2026
a91719a
lldp: fix _set_arg_info output label
m-hau Nov 17, 2025
0ce127c
lldp: fix test_arg_ipv6
m-hau Nov 17, 2025
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
130 changes: 120 additions & 10 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,16 @@ jobs:
strategy:
matrix:
include:
- version: 7
os: ubuntu-20.04
- version: 8
os: ubuntu-20.04
- version: 9
os: ubuntu-20.04
- version: 10
os: ubuntu-20.04
- version: 11
os: ubuntu-20.04
- version: 12
os: ubuntu-22.04
- version: 13
os: ubuntu-22.04
- version: 14
os: ubuntu-24.04
- version: 15
os: ubuntu-24.04
- version: 16
os: ubuntu-24.04
fail-fast: false

runs-on: ${{ matrix.os }}
Expand Down Expand Up @@ -67,3 +61,119 @@ jobs:

- name: Run distcheck
run: make distcheck

integration-tests:
# The test/pytest/ netns+scapy suite (basic LLDP behavior, the
# IEEE 802.1AB compliance cases, and the ported qbg22 EVB/ECP/VDP
# suite - qbg22's cases with known, tracked mismatches skip
# themselves by default, see test/pytest/qbg/known_failures.py).
# --enable-debug so qbg22sim/vdptest get built and those cases run
# too, not just skip for missing binaries.
runs-on: ubuntu-24.04
timeout-minutes: 30

steps:
- uses: actions/checkout@v4

- name: Install dependencies
run: >
sudo apt-get install -y
libconfig-dev libnl-3-dev libnl-genl-3-dev
linux-libc-dev libreadline-dev

- uses: actions/setup-python@v5
with:
python-version: "3.x"

- name: Install python test dependencies
run: pip install -r test/pytest/requirements.txt

- name: Run bootstrap
run: ./bootstrap.sh

- name: Configure project
run: ./configure --enable-debug --enable-warnings --enable-errors

- name: Build
run: make -j"$(nproc)"

- name: Run check-integration
# Real root, plain `ip netns add`/`ip netns exec` (no user
# namespace involved at all) - see test/pytest/README.md's
# "Privilege model" for why: this harness first tried running
# unprivileged via a remapped user namespace, but that hit
# Ubuntu 23.10+'s AppArmor restriction on unprivileged
# CLONE_NEWUSER; running that same construction as real root to
# sidestep the restriction then produced its own unexplained
# "Permission denied" execing freshly-built binaries through the
# nested namespace. Skipping user namespaces entirely avoids
# both. `-E ... PATH=$PATH` so sudo doesn't drop the toolchain
# (pytest, the built binaries) off PATH.
run: sudo -E env "PATH=$PATH" make check-integration

sanitizers:
# Same build+test, compiled with -fsanitize=address or =undefined.
# Not a required check yet (continue-on-error): the goal for now is
# visibility into what these turn up, not blocking merges on
# findings that haven't been triaged - see PR discussion. The
# test/pytest/ suites (deliberately feeding lldpad malformed/edge
# case data) are exactly where a sanitizer earns its keep, so this
# runs check-integration too, not just the unit test binary - and
# already found a real one while this job was being put together:
# a heap-buffer-overflow read in rxProcessFrame() (lldp/rx.c) on a
# truly tiny malformed frame.
#
# ASan needs -static-libasan: lldpad/lldptool are libtool wrapper
# scripts around the real binary in .libs/, and ASan's runtime has
# to be the first thing loaded (it intercepts malloc/free) - through
# that wrapper indirection it isn't, and every ASan-built binary
# exits immediately complaining "ASan runtime does not come first in
# initial library list" without it. UBSan's runtime doesn't
# intercept anything, so it isn't affected the same way and doesn't
# need the static-link workaround.
runs-on: ubuntu-24.04
timeout-minutes: 30
continue-on-error: true
strategy:
matrix:
include:
- sanitizer: address
extra_ldflags: -static-libasan
- sanitizer: undefined
extra_ldflags: ""
fail-fast: false

steps:
- uses: actions/checkout@v4

- name: Install dependencies
run: >
sudo apt-get install -y
libconfig-dev libnl-3-dev libnl-genl-3-dev
linux-libc-dev libreadline-dev

- uses: actions/setup-python@v5
with:
python-version: "3.x"

- name: Install python test dependencies
run: pip install -r test/pytest/requirements.txt

- name: Run bootstrap
run: ./bootstrap.sh

- name: Configure project
run: >
./configure --enable-debug
CFLAGS="-fsanitize=${{ matrix.sanitizer }} -fno-omit-frame-pointer -g -O1"
LDFLAGS="-fsanitize=${{ matrix.sanitizer }} ${{ matrix.extra_ldflags }}"

- name: Build
run: make -j"$(nproc)"

- name: Run check
run: make check

- name: Run check-integration
# See the integration-tests job for why this is sudo -E ... PATH=$PATH.
run: sudo -E env "PATH=$PATH" make check-integration
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,8 @@ qbg22sim
patches/
tags
ar-lib

# pytest netns/scapy test suite
test/pytest/**/__pycache__/
test/pytest/.pytest_cache/
test/pytest/.scratch/
55 changes: 55 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ lldptool_LDFLAGS = -ldl -llldp_clif $(LIBNL_LIBS)
if BUILD_DEBUG
nltest_SOURCES = test/nltest.c test/nltest.h
vdptest_SOURCES = test/vdptest.c
vdptest_LDADD = liblldp_clif.la
vdptest_LDFLAGS = -llldp_clif
qbg22sim_SOURCES = test/qbg22sim.c
qbg22sim_LDFLAGS = -lrt
Expand All @@ -116,6 +117,20 @@ endif
## put a spec file and documentation in the distribution archive
dist_noinst_DATA = lldpad.spec README COPYING ChangeLog lldpad.init

## netns/scapy integration test suite sources (see check-integration below)
EXTRA_DIST = test/pytest

## strip Python bytecode caches (created by running check-integration
## in-tree) out of both `make clean` and `make dist` output; they're
## build artifacts, not sources.
clean-local:
find $(srcdir)/test/pytest -name '__pycache__' -type d -exec rm -rf {} +
rm -rf $(srcdir)/test/pytest/.pytest_cache

dist-hook:
find $(distdir)/test/pytest -name '__pycache__' -type d -exec rm -rf {} +
rm -rf $(distdir)/test/pytest/.pytest_cache

## man pages
dist_man_MANS = docs/lldpad.8 docs/dcbtool.8 docs/lldptool.8 \
docs/lldptool-ets.8 docs/lldptool-pfc.8 docs/lldptool-app.8 \
Expand Down Expand Up @@ -151,6 +166,46 @@ lldp_clif_test_SOURCES = test/lldp_clif_test.c lldp_basman_clif.c lldp_util.c \
lldp_rtnl.c
lldp_clif_test_LDFLAGS = -lrt $(LIBNL_LIBS)

## netns/scapy integration test suite (test/pytest/): not part of the
## default `check` since it needs pytest+scapy and real root (to create
## network namespaces - see test/pytest/README.md's "Privilege model"),
## neither of which every build host has. Run explicitly with
## `sudo make check-integration` (individual cases skip themselves
## cleanly, rather than failing, if run without root).
##
## This also covers test/pytest/qbg/, the ported test/qbg22/ EVB/ECP/VDP
## case suite - but that one additionally needs qbg22sim and vdptest,
## which are noinst_PROGRAMS built only with --enable-debug; without it,
## those cases skip themselves cleanly at test time rather than failing
## the build here.
##
## Cases run in parallel (pytest-xdist, `-n auto`) by default - `make -j`
## does *not* parallelize this, since check-integration is one target
## with one recipe (one pytest invocation); the actual concurrency knob
## is PYTEST below. Override e.g. `make check-integration PYTEST=pytest`
## to force serial, or `PYTEST="pytest -n 4"` to pick a worker count.
PYTEST ?= pytest -n auto

if BUILD_DEBUG
QBG_TEST_BINS = qbg22sim$(EXEEXT) vdptest$(EXEEXT)
else
QBG_TEST_BINS =
endif

.PHONY: check-integration
check-integration: lldpad$(EXEEXT) lldptool$(EXEEXT) vdptool$(EXEEXT) $(QBG_TEST_BINS)
@pytest_bin=`echo $(PYTEST) | awk '{print $$1}'`; \
if ! command -v "$$pytest_bin" >/dev/null 2>&1; then \
echo "error: '$$pytest_bin' not found; install $(srcdir)/test/pytest/requirements.txt" >&2; \
exit 1; \
fi
OPENLLDP_LLDPAD=$(abs_builddir)/lldpad$(EXEEXT) \
OPENLLDP_LLDPTOOL=$(abs_builddir)/lldptool$(EXEEXT) \
OPENLLDP_VDPTOOL=$(abs_builddir)/vdptool$(EXEEXT) \
OPENLLDP_QBG22SIM=$(abs_builddir)/qbg22sim$(EXEEXT) \
OPENLLDP_VDPTEST=$(abs_builddir)/vdptest$(EXEEXT) \
$(PYTEST) $(srcdir)/test/pytest -v

RPMBUILD_TOP = $(abs_top_builddir)/rpm/rpmbuild
RPMBUILD_OPT ?= --without check

Expand Down
Loading
Loading