From 9f82e189708f6941a0baf3e41d87768e7869e000 Mon Sep 17 00:00:00 2001 From: Denys Fedoryshchenko Date: Wed, 28 Oct 2026 20:47:22 +0200 Subject: docs: clarify CMake requirements for build and test commands Keep the CMake 3.10 project minimum while documenting the newer CLI requirements. Add a build-directory/install-target alternative for older CMake and state the CTest requirement in the test guide. Validation: shell examples pass bash -n; local documentation links resolve. Signed-off-by: Denys Fedoryshchenko --- tests/README.md | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tests') diff --git a/tests/README.md b/tests/README.md index 870cf8c8..ac8d016b 100644 --- a/tests/README.md +++ b/tests/README.md @@ -2,6 +2,11 @@ These tests are done for Ubuntu and Debian distros. Please use latest stable Debian or Ubuntu to run the tests. +The commands in this guide require CMake/CTest 3.20 or newer, including +`ctest --test-dir`. The standalone kernel-module installation script requires +CMake 3.15 or newer for `cmake --install`. These command requirements are +separate from the project's minimum CMake version of 3.10. + ## Focused unit tests The standalone unit tests compile production callbacks with small test fixtures -- cgit v1.2.3 From a9e7d43596c5d524b2fe9300102ab8fe20c987f5 Mon Sep 17 00:00:00 2001 From: Denys Fedoryshchenko Date: Wed, 28 Oct 2026 20:47:22 +0200 Subject: docs: specify Lua 5.1 dependencies and numeric version matching Explain that LUA=TRUE uses FindLua51, while numeric LUA values use non-EXACT FindLua version matching. Name the Lua 5.1 development package required by the test build examples. Validation: checked against accel-pppd/CMakeLists.txt and the installed FindLua51 module. Signed-off-by: Denys Fedoryshchenko --- README.md | 4 +++- tests/README.md | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/README.md b/README.md index bac35421..80b0aeaa 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,9 @@ development libraries: * Net-SNMP for NETSNMP=TRUE * PostgreSQL client libraries for LOG_PGSQL_DEPRECATED=TRUE -* Lua for LUA=TRUE or a specific Lua version such as LUA=5.3 +* Lua 5.1 development files for LUA=TRUE. A numeric value such as LUA=5.3 + requests at least that Lua version through CMake's FindLua module; it does + not enforce an exact version. Building and installing diff --git a/tests/README.md b/tests/README.md index ac8d016b..abf3704e 100644 --- a/tests/README.md +++ b/tests/README.md @@ -74,7 +74,8 @@ sudo apt install iproute2 ppp pppoe isc-dhcp-client ``` Install the build dependencies described in the project README, including -kernel headers and Lua development files for the options below. Run these +kernel headers and Lua 5.1 development files (`liblua5.1-0-dev` on Debian and +Ubuntu) for `LUA=TRUE` below. Run these commands from the repository root. Install accel-pppd (make install or use distro package). Do not run accel-pppd using systemd or other supervisors -- cgit v1.2.3 From 69cfe9cc7c03f663bcbc430291bc3a9460e433ba Mon Sep 17 00:00:00 2001 From: Denys Fedoryshchenko Date: Wed, 28 Oct 2026 20:47:22 +0200 Subject: tests: fix DHCPv6 fixtures after DNS refactoring and add CI coverage Use the shared DNS storage and production allocator in the DHCPv6 fixture. Check bounded large DNS replies, preserve the repeated-ORO overflow regression, and check domain-list allocation failure in both reply builders. Link ipv6_dns.c and stub the truncation warning. Run the standalone suites and CTest in sanitizer CI, and replace the stale documented failure with current instructions. Validation: all six standalone suites pass with ASan/UBSan (LCP uses UBSan); both CTest checks pass. Signed-off-by: Denys Fedoryshchenko --- .github/workflows/run-tests-asan-ubsan.yml | 2 + CHANGELOG.md | 8 ++-- docs/ng40-safeguards-review.md | 8 ++-- tests/README.md | 12 ++---- tests/unit/dhcpv6_safeguards_test.c | 69 +++++++++++++++++++++++++++++- tests/unit/run_safeguards.sh | 6 ++- 6 files changed, 86 insertions(+), 19 deletions(-) (limited to 'tests') diff --git a/.github/workflows/run-tests-asan-ubsan.yml b/.github/workflows/run-tests-asan-ubsan.yml index 0ee2c755..77586419 100644 --- a/.github/workflows/run-tests-asan-ubsan.yml +++ b/.github/workflows/run-tests-asan-ubsan.yml @@ -64,6 +64,7 @@ jobs: env: ${{ matrix.env_name }}: ${{ matrix.env_value }} run: | + ctest --test-dir build --output-on-failure gcc -O1 -g -Wall -fno-strict-aliasing -D_GNU_SOURCE \ -DOPENSSL_API_COMPAT=0x10100000L \ -fsanitize=${{ matrix.sanitizer }} -fno-sanitize-recover=all \ @@ -80,6 +81,7 @@ jobs: /tmp/ipv6_dns_test gcc -O2 -Wall -o /tmp/bitpool_test accel-pppd/extra/bitpool_test.c /tmp/bitpool_test + sh tests/unit/run_safeguards.sh build - name: Insert and check kernel modules (ipoe, vlan-mon, ppposeq) # if: ${{ false }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 536bb024..27e13264 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -97,13 +97,13 @@ - Added contribution guidelines and a safeguard integration review. - Corrected RADIUS option examples, shaper units and directions, kernel module requirements, metrics freshness guidance, and the accel-cmd - timeout synopsis. Updated test setup instructions and documented the - current DHCPv6 safeguard fixture limitation. + timeout synopsis. Updated test setup instructions. ### Tests / CI - Added focused suites for DHCPv6, RADIUS, VRF, LCP, memory pools, logging, - L2TP, IPv6 DNS, and bitmap allocation. See `tests/README.md` for the - current standalone safeguard runner limitation. + L2TP, IPv6 DNS, and bitmap allocation. Updated the DHCPv6 safeguard fixture + for shared DNS storage and bounded replies, and run all six standalone + safeguard suites in sanitizer CI. - Added metrics, IPoE stale-interface cleanup and link deletion, PPPoE negotiation, and kernel-module installation regression coverage. - Added Ubuntu 26.04 coverage and removed Debian 11 jobs. Continue testing diff --git a/docs/ng40-safeguards-review.md b/docs/ng40-safeguards-review.md index 8dfbe32e..9ba08977 100644 --- a/docs/ng40-safeguards-review.md +++ b/docs/ng40-safeguards-review.md @@ -107,10 +107,10 @@ git diff --check ``` For current checkouts, see the [focused unit test instructions](../tests/README.md#focused-unit-tests). -The later IPv6 DNS storage refactor removed `conf_dns_count`, which the -DHCPv6 fixture still references, and the runner needs to link `ipv6_dns.c`. -The full command above therefore does not currently compile on master. The -historical results below do not establish that the current full suite passes. +The DHCPv6 fixture now uses the shared IPv6 DNS storage and its production +implementation. It checks safe truncation of oversized DNS replies and +failure propagation when domain-list options exhaust reply space. The +sanitizer workflow also runs the complete standalone safeguard suite. Build, the existing IPv6 DNS selection test, and five standalone suites passed. Tests compile production code with small external-service stubs. DHCPv6, RADIUS, VRF, and pool tests use ASan, diff --git a/tests/README.md b/tests/README.md index abf3704e..d89958e1 100644 --- a/tests/README.md +++ b/tests/README.md @@ -21,18 +21,14 @@ These tests do not require installed kernel modules or root privileges. The sanitizer runtime needs an environment that permits its process inspection. The runner has six suites: `dhcpv6`, `radius`, `vrf`, `lcp`, `mempool`, and -`log_line`. With no names it attempts all six. The DHCPv6 fixture currently -refers to the removed `conf_dns_count` variable, and the runner does not link -the `ipv6_dns.c` implementation now used by the reply builder. That fixture -and its build command must be updated before a full run can pass. - -The other five suites can be run explicitly while that regression is being fixed: +`log_line`. With no names it runs all six: ```bash -sh tests/unit/run_safeguards.sh build radius vrf lcp mempool log_line +sh tests/unit/run_safeguards.sh build ``` -A successful subset run does not validate the DHCPv6 safeguards. The +The DHCPv6 suite checks bounded DNS replies and failure propagation when +non-truncatable options exhaust reply space. The [integration validation record](../docs/ng40-safeguards-review.md#validation) describes results from the revision at which those safeguards were introduced. diff --git a/tests/unit/dhcpv6_safeguards_test.c b/tests/unit/dhcpv6_safeguards_test.c index 63692ee3..0938047c 100644 --- a/tests/unit/dhcpv6_safeguards_test.c +++ b/tests/unit/dhcpv6_safeguards_test.c @@ -14,6 +14,7 @@ static size_t response_len; void log_warn(const char *fmt, ...) {} void log_emerg(const char *fmt, ...) {} void log_ppp_error(const char *fmt, ...) {} +void log_ppp_warn(const char *fmt, ...) {} void log_ppp_info2(const char *fmt, ...) {} int ip6addr_add_peer(int i, struct in6_addr *a, struct in6_addr *p) { return 0; } int ip6route_add(int i, const struct in6_addr *a, int p, const struct in6_addr *g, int m, uint32_t prio, const char *v) { return 0; } @@ -60,10 +61,36 @@ static size_t relay(unsigned char *buf, size_t len) return len + hdrlen + 4; } +static void check_dns_reply(unsigned int requested) +{ + struct dhcpv6_packet *pkt; + struct dhcpv6_option *opt; + unsigned int count = 0; + size_t offset, len; + + assert(sent == 1); + assert(response_len <= sizeof(response)); + pkt = dhcpv6_packet_parse(response, response_len); + assert(pkt); + list_for_each_entry(opt, &pkt->opt_list, entry) { + if (ntohs(opt->hdr->code) != D6_OPTION_DNS_SERVERS) + continue; + len = ntohs(opt->hdr->len); + assert(len && len % sizeof(struct in6_addr) == 0); + for (offset = 0; offset < len; offset += sizeof(struct in6_addr)) + assert(!memcmp(opt->hdr->data + offset, &in6addr_loopback, + sizeof(in6addr_loopback))); + count += len / sizeof(struct in6_addr); + } + assert(count > 0 && count < requested); + dhcpv6_packet_free(pkt); +} + int main(void) { unsigned char buf[16000], oro[4000], name[256]; const unsigned char valid_name[] = {2, 'g', 'w', 0}; + unsigned char domain[] = {1, 'x', 0}; struct dhcpv6_packet *pkt, *reply; struct dhcpv6_option *opt; struct ap_session ses = {0}; @@ -132,8 +159,27 @@ int main(void) } assert(!dhcpv6_packet_parse(buf, len)); - /* An ORO can amplify a small request into more than 4096 response bytes. */ - conf_dns_count = 1; + /* A large DNS list is truncated to the reply buffer capacity. */ + assert(ipv6_dns_reserve(&conf_dns, 300) == 0); + for (i = 0; i < 300; i++) + conf_dns.addr[i] = in6addr_loopback; + conf_dns.count = 300; + u_write_be16(oro, D6_OPTION_DNS_SERVERS); + len = request(buf); + len += option(buf + len, D6_OPTION_ORO, oro, 2); + pkt = dhcpv6_packet_parse(buf, len); + assert(pkt); + pkt->ses = &ses; + sent = 0; + dhcpv6_send_reply(pkt, &pd, D6_REPLY); + check_dns_reply(conf_dns.count); + sent = 0; + dhcpv6_send_reply2(pkt, &pd, D6_REPLY); + check_dns_reply(conf_dns.count); + dhcpv6_packet_free(pkt); + + /* Repeated ORO entries leave no room for the final Preference option. */ + conf_dns.count = 1; for (i = 0; i < sizeof(oro); i += 2) u_write_be16(oro + i, D6_OPTION_DNS_SERVERS); len = request(buf); @@ -147,6 +193,25 @@ int main(void) dhcpv6_send_reply2(pkt, &pd, D6_REPLY); assert(!sent); dhcpv6_packet_free(pkt); + free(conf_dns.addr); + memset(&conf_dns, 0, sizeof(conf_dns)); + + /* Domain-list options cannot be shortened; exhaustion drops the reply. */ + conf_dnssl = domain; + conf_dnssl_size = sizeof(domain); + for (i = 0; i < sizeof(oro); i += 2) + u_write_be16(oro + i, D6_OPTION_DOMAIN_LIST); + len = request(buf); + len += option(buf + len, D6_OPTION_ORO, oro, sizeof(oro)); + pkt = dhcpv6_packet_parse(buf, len); + assert(pkt); + pkt->ses = &ses; + sent = 0; + dhcpv6_send_reply(pkt, &pd, D6_REPLY); + assert(!sent); + dhcpv6_send_reply2(pkt, &pd, D6_REPLY); + assert(!sent); + dhcpv6_packet_free(pkt); puts("DHCPv6 safeguards: PASS"); return 0; } diff --git a/tests/unit/run_safeguards.sh b/tests/unit/run_safeguards.sh index 7f18c492..001cd19e 100644 --- a/tests/unit/run_safeguards.sh +++ b/tests/unit/run_safeguards.sh @@ -13,11 +13,15 @@ for name in $names; do # LCP's global layer table retains the whole daemon under ASan; its test # checks wire lengths with UBSan. The packet/VRF tests also use ASan. if [ "$name" = lcp ]; then extra=-fno-sanitize=address; fi + set -- "tests/unit/${name}_safeguards_test.c" + if [ "$name" = dhcpv6 ]; then + set -- "$@" accel-pppd/ipv6_dns.c + fi ${CC:-cc} -O1 -g -Wall -Wno-unused-function -Wno-unused-result -D_GNU_SOURCE -DAP_SESSIONID_LEN=16 \ -DOPENSSL_API_COMPAT=0x10100000L -fno-strict-aliasing \ -ffunction-sections -fdata-sections -Wl,--gc-sections \ -fsanitize=address,undefined -fno-sanitize-recover=all $extra \ -I "$build" -I accel-pppd -I accel-pppd/include -I accel-pppd/triton \ - -o "$out/$name" "tests/unit/${name}_safeguards_test.c" -lcrypto -lpthread + -o "$out/$name" "$@" -lcrypto -lpthread "$out/$name" done -- cgit v1.2.3 From 2fa7676c2d01f5757db99463a7ae4ab28841570d Mon Sep 17 00:00:00 2001 From: Denys Fedoryshchenko Date: Wed, 28 Oct 2026 20:47:22 +0200 Subject: cmake: include PPPoSEQ in Debian and RPM package installs Add the missing PPPoSEQ install rules and standalone driver metadata. Supply the running kernel release as the default RPM module destination. Extend the rootless install regression to verify Debian/CentOS packaging names, staged module paths, and exclusion after disabling the build flag. Validation: CTest passes; generated full and standalone DEBs contain ppposeq.ko and have the expected package names. RPM install rules were staged and checked; an RPM archive was not built because rpmbuild is unavailable. Signed-off-by: Denys Fedoryshchenko --- CHANGELOG.md | 2 ++ cmake/centos/centos.cmake | 18 ++++++++++++++++++ cmake/debian/debian.cmake | 11 +++++++++++ tests/README.md | 3 +++ tests/kernel-module-install/test.sh | 31 +++++++++++++++++++++++++++++++ 5 files changed, 65 insertions(+) (limited to 'tests') diff --git a/CHANGELOG.md b/CHANGELOG.md index 27e13264..17e753d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -90,6 +90,8 @@ VLAN monitoring packet-handler registration on Linux 6.6 and newer. - Build / install: install kernel modules from their actual build directories, honor `DESTDIR`, and propagate installation failures. +- Packaging: include the optional PPPoSEQ kernel module in Debian and RPM + installation rules, including standalone driver packages. ### Docs - Refreshed the README and synchronized the sample configuration and man diff --git a/cmake/centos/centos.cmake b/cmake/centos/centos.cmake index a0dcd279..00cd0c6a 100644 --- a/cmake/centos/centos.cmake +++ b/cmake/centos/centos.cmake @@ -1,6 +1,14 @@ SET(CPACK_PACKAGING_INSTALL_PREFIX "/usr") SET(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}) +if (NOT DEFINED CENTOS_KDIR) + execute_process( + COMMAND uname -r + OUTPUT_VARIABLE CENTOS_KDIR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +endif () + if (BUILD_DRIVER_ONLY) if (BUILD_IPOE_DRIVER) SET(CPACK_PACKAGING_INSTALL_PREFIX "/") @@ -22,3 +30,13 @@ else (BUILD_DRIVER_ONLY) INSTALL(FILES ${CMAKE_HOME_DIRECTORY}/accel-pppd/accel-ppp.conf DESTINATION /etc RENAME accel-ppp.conf.dist) endif (BUILD_DRIVER_ONLY) +if (BUILD_PPPOSEQ_DRIVER) + if (BUILD_DRIVER_ONLY) + SET(CPACK_PACKAGING_INSTALL_PREFIX "/") + SET(CPACK_PACKAGE_NAME "accel-ppp-ppposeq-kmod") + SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "accel-ppp PPPoSEQ kernel module") + SET(CPACK_RPM_PACKAGE_REQUIRES "") + endif () + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/drivers/ppposeq/driver/ppposeq.ko DESTINATION /lib/modules/${CENTOS_KDIR}/extra) +endif (BUILD_PPPOSEQ_DRIVER) + diff --git a/cmake/debian/debian.cmake b/cmake/debian/debian.cmake index 89ab9993..1b6ab8ce 100644 --- a/cmake/debian/debian.cmake +++ b/cmake/debian/debian.cmake @@ -31,6 +31,17 @@ if (BUILD_VLAN_MON_DRIVER) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/drivers/vlan_mon/driver/vlan_mon.ko DESTINATION /lib/modules/${MODULES_KDIR}/extra) endif (BUILD_VLAN_MON_DRIVER) +if (BUILD_PPPOSEQ_DRIVER) + if (BUILD_DRIVER_ONLY) + SET(CPACK_PACKAGING_INSTALL_PREFIX "/") + SET(CPACK_PACKAGE_NAME "accel-ppp-ppposeq-kmod") + SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "accel-ppp PPPoSEQ kernel module") + SET(CPACK_DEBIAN_PACKAGE_DEPENDS "") + SET(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian-kmod/postinst") + endif () + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/drivers/ppposeq/driver/ppposeq.ko DESTINATION /lib/modules/${MODULES_KDIR}/extra) +endif (BUILD_PPPOSEQ_DRIVER) + if (NOT BUILD_DRIVER_ONLY) SET(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/postinst;${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/conffiles") diff --git a/tests/README.md b/tests/README.md index d89958e1..44bae6a4 100644 --- a/tests/README.md +++ b/tests/README.md @@ -38,6 +38,9 @@ The kernel module installation regression test is rootless and does not need kernel headers. It uses a fake kernel build tree to verify that `ipoe`, `vlan_mon`, and `ppposeq` are installed from their actual build directories, honor `DESTDIR`, and make installation fail when `modules_install` fails. +It also verifies that Debian and CentOS packaging configurations include +`ppposeq.ko` with the standalone driver package name, and omit it when the +build flag is disabled. Run it through CTest after configuring the project: diff --git a/tests/kernel-module-install/test.sh b/tests/kernel-module-install/test.sh index 1fbfd623..2f3ec579 100644 --- a/tests/kernel-module-install/test.sh +++ b/tests/kernel-module-install/test.sh @@ -36,3 +36,34 @@ if FAIL_MODULES_INSTALL=1 DESTDIR="${work_dir}/failed-stage" \ fi grep -q 'Failed to install kernel module' "${work_dir}/failed-install.log" + +# Packaging configurations bypass modules_install and must install the .ko +# explicitly, including when PPPoSEQ is built as a standalone driver package. +for package_type in Debian12 Centos9; do + package_build="${work_dir}/package-${package_type}" + package_stage="${work_dir}/stage-${package_type}" + "${cmake_command}" \ + -S "${source_dir}" \ + -B "${package_build}" \ + -DBUILD_TESTING=OFF \ + -DBUILD_DRIVER_ONLY=TRUE \ + -DBUILD_PPPOSEQ_DRIVER=TRUE \ + -DIGNORE_GIT=TRUE \ + -DCPACK_TYPE="${package_type}" \ + -DMODULES_KDIR=test-kernel \ + -DCENTOS_KDIR=test-kernel \ + -DKDIR="${script_dir}" + "${cmake_command}" --build "${package_build}" + DESTDIR="${package_stage}" \ + "${cmake_command}" --install "${package_build}" + test -f "${package_stage}/lib/modules/test-kernel/extra/ppposeq.ko" + grep -q 'set(CPACK_PACKAGE_NAME "accel-ppp-ppposeq-kmod")' \ + "${package_build}/CPackConfig.cmake" + + # A stale build artifact must not be installed after the flag is disabled. + "${cmake_command}" -S "${source_dir}" -B "${package_build}" \ + -DBUILD_PPPOSEQ_DRIVER=FALSE + DESTDIR="${package_stage}-disabled" \ + "${cmake_command}" --install "${package_build}" + test ! -e "${package_stage}-disabled/lib/modules/test-kernel/extra/ppposeq.ko" +done -- cgit v1.2.3