diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3527e735..27a4ccfa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - distro: [focal] + distro: [focal, noble] steps: - uses: actions/checkout@v6 - name: Run package build ${{ matrix.distro }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3cd38a43..e35dde75 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,7 @@ jobs: strategy: fail-fast: false matrix: - distro: [focal] + distro: [focal, noble] steps: - name: Checkout code uses: actions/checkout@v6 @@ -49,7 +49,14 @@ jobs: fail-fast: false matrix: test-suite: [director, director-xdp, healthcheck, redirect] - distro: [focal] + distro: [focal, noble] + exclude: + # The DPDK-based glb-director only builds on focal (DPDK 17 / KNI). + # On other distros the supported forwarder is glb-director-xdp, so + # skip the director suite there. This mirrors the same exclusion in + # script/test-local. + - distro: noble + test-suite: director steps: - name: Checkout code uses: actions/checkout@v6 diff --git a/Makefile b/Makefile index c94302a5..a69dbf59 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,23 @@ +# Set GLB_SKIP_DPDK_DIRECTOR=1 to skip building the DPDK glb-director package. +# In that mode we still build glb-director-cli (a runtime dep of glb-director-xdp) +# via GLB_CLI_ONLY=1. This is used on distros where DPDK 17 / KNI is unavailable +# (e.g. Ubuntu noble). +GLB_SKIP_DPDK_DIRECTOR ?= + mkdeb: make -C src/glb-redirect mkdeb make -C src/glb-healthcheck mkdeb cd src/glb-director-xdp && script/create-packages +ifeq ($(GLB_SKIP_DPDK_DIRECTOR),1) + cd src/glb-director && GLB_CLI_ONLY=1 script/create-packages +else cd src/glb-director && script/create-packages +endif clean: make -C src/glb-redirect clean make -C src/glb-healthcheck clean +ifneq ($(GLB_SKIP_DPDK_DIRECTOR),1) make -C src/glb-director clean +endif make -C src/glb-director/cli clean diff --git a/script/Dockerfile.noble b/script/Dockerfile.noble new file mode 100644 index 00000000..6741599d --- /dev/null +++ b/script/Dockerfile.noble @@ -0,0 +1,107 @@ +FROM --platform=linux/amd64 ubuntu:noble@sha256:c4a8d5503dfb2a3eb8ab5f807da5bc69a85730fb49b5cfca2330194ebcc41c7b + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get -y install curl git + +# Build deps for glb-director-cli and glb-director-xdp. +# Note: we do NOT install DPDK on noble. The DPDK-based glb-director is only +# built on focal; on noble the supported forwarder is glb-director-xdp. +RUN apt-get update && apt-get install --assume-yes \ + build-essential \ + wget \ + pkg-config \ + libjansson-dev \ + libsystemd-dev + +# iptables / DKMS +RUN apt-get update +RUN apt-get install --assume-yes --fix-broken \ + wget \ + pkg-config \ + libsystemd-dev \ + dkms \ + dh-dkms \ + dpkg-dev \ + fakeroot \ + debhelper \ + libxtables-dev + +# noble's dkms 3.x dropped `dkms mkdeb`, which the glb-redirect Makefile needs +# (template-dkms-mkdeb + `dkms mkdeb --source-only`). Restore it by extracting +# focal's dkms 2.x alongside 3.x and shimming `dkms mkdeb` to the legacy binary. +# +# We `apt-get download` the focal dkms from a GPG-verified focal source (full +# apt chain of trust, no hardcoded/unverified URL). The focal pockets are +# pinned below noble's so they're only used for this download, never installs. +RUN set -eux; \ + keyring=/usr/share/keyrings/ubuntu-archive-keyring.gpg; \ + printf 'deb [signed-by=%s] http://archive.ubuntu.com/ubuntu focal main\ndeb [signed-by=%s] http://archive.ubuntu.com/ubuntu focal-updates main\n' "$keyring" "$keyring" > /etc/apt/sources.list.d/focal-dkms.list; \ + printf 'Package: *\nPin: release n=focal\nPin-Priority: 100\n\nPackage: *\nPin: release n=focal-updates\nPin-Priority: 100\n' > /etc/apt/preferences.d/focal-dkms.pref; \ + apt-get update; \ + # Sanity check: the focal pin must not change the dkms candidate (stays 3.x). + case "$(apt-cache policy dkms | awk '/Candidate:/{print $2}')" in 3.*) : ;; *) echo "ERROR: dkms candidate changed by focal pin" >&2; exit 1 ;; esac; \ + cd /tmp; \ + apt-get download dkms/focal-updates; \ + deb="$(ls dkms_*_all.deb)"; \ + dpkg-deb -x "$deb" /tmp/dkms-focal; \ + cp -r /tmp/dkms-focal/etc/dkms/template-dkms-mkdeb /etc/dkms/template-dkms-mkdeb; \ + install -m 0755 /tmp/dkms-focal/usr/sbin/dkms /usr/sbin/dkms-legacy; \ + rm -rf /tmp/dkms-focal "/tmp/$deb"; \ + # Remove the temporary focal source + pin so they don't linger in the image. + rm -f /etc/apt/sources.list.d/focal-dkms.list /etc/apt/preferences.d/focal-dkms.pref; \ + apt-get update; \ + printf '#!/bin/sh\nif [ "$1" = "mkdeb" ]; then exec /usr/sbin/dkms-legacy "$@"; fi\nexec /usr/sbin/dkms.real "$@"\n' > /usr/local/bin/dkms; \ + chmod 0755 /usr/local/bin/dkms; \ + mv /usr/sbin/dkms /usr/sbin/dkms.real + +# golang +RUN ARCH=$(dpkg --print-architecture) && wget --quiet https://golang.org/dl/go1.24.5.linux-${ARCH}.tar.gz -O- | tar -C /usr/local -zxvf - +ENV GOROOT /usr/local/go +ENV GOPATH /go +ENV GOFLAGS=-buildvcs=false +ENV PATH="${GOPATH}/bin:${GOROOT}/bin:${PATH}" + + +# fpm for packaging +RUN apt-get update && apt-get install -y ruby ruby-dev rubygems build-essential + +# See fpm dependency breakage issue: https://github.com/jordansissel/fpm/issues/1918 +RUN gem install --version 2.7.6 dotenv +RUN gem install ffi -f +RUN gem install rake fpm + +# XDP +# linux-libc-dev must be upgraded to get a bpf.h that matches what we use. the rest match what we do in Vagrant for testing. +RUN apt-get update && apt install -y apt-transport-https curl software-properties-common +RUN apt-get update && apt install -y iproute2 libbpf-dev linux-libc-dev clang-20 clang-tools-20 + +# The xdp bpf/Makefile defaults CLANG/LLC to clang-10/llc-10 (focal). On noble +# we ship clang-20 instead, so steer the BPF build at it. +ENV CLANG=clang-20 +ENV LLC=llc-20 + + +# Hack because the kernel headers are not installed in the right place (linuxkit vs generic) +RUN ln -s /usr/src/$(ls /usr/src/ | grep generic) /usr/src/linux-headers-$(uname -r) + +# Hack for C99 math +RUN sed -i '1s/^/#define __USE_C99_MATH\n/' /usr/src/$(ls /usr/src/ | grep generic)/include/linux/kasan-checks.h +RUN sed -i '2s/^/#include \n/' /usr/src/$(ls /usr/src/ | grep generic)/include/linux/kasan-checks.h + +# Newer kernel headers (6.8 in noble) added linux/kcsan-checks.h which uses +# `size_t` without pulling stddef.h, breaking the bpf clang build. Inject a +# stddef.h up front, mirroring the kasan-checks.h hack above. +RUN sed -i '1s|^|#include \n|' /usr/src/$(ls /usr/src/ | grep generic)/include/linux/kcsan-checks.h + + +# Python test dependencies (scapy/pytest etc.) used by the test suites. +RUN apt-get update && apt-get install -y python3 python3-pip python3-dev +COPY requirements.txt /tmp/requirements.txt +RUN pip3 install --no-cache-dir --break-system-packages -r /tmp/requirements.txt + +# valgrind is required by the glb-director test suite +RUN apt-get update && apt-get install -y valgrind + +# netcat and jq are required by the glb-healthcheck test suite +RUN apt-get update && apt-get install -y netcat-openbsd jq tcpdump diff --git a/script/cibuild-create-packages b/script/cibuild-create-packages index 4d1d2cd4..386900eb 100755 --- a/script/cibuild-create-packages +++ b/script/cibuild-create-packages @@ -30,10 +30,18 @@ begin_fold "Building packages" rm -rf tmp/build/ mkdir -p tmp/build/ + # The DPDK glb-director sub-build only works on focal (DPDK 17 / KNI). + # On other distros we skip it but still produce glb-director-cli (a runtime + # dep of glb-director-xdp). + EXTRA_MAKE_ENV="" + if [ "$DISTRO" != "focal" ]; then + EXTRA_MAKE_ENV="GLB_SKIP_DPDK_DIRECTOR=1" + fi + docker run --rm \ --volume "$HOSTPATH":/glb-director \ "glb-director-build-$DISTRO" \ bash -c "cd /glb-director && - make BUILDDIR=/glb-director/tmp/build clean mkdeb" + make BUILDDIR=/glb-director/tmp/build $EXTRA_MAKE_ENV clean mkdeb" ) end_fold \ No newline at end of file diff --git a/script/test-local b/script/test-local index 76fb2ec3..f029cdbb 100755 --- a/script/test-local +++ b/script/test-local @@ -25,7 +25,13 @@ cd "$HOSTPATH" echo "==> Building Docker image for ${DISTRO}..." docker build --platform linux/amd64 --file "${DOCKERFILE}" --tag "${IMAGE}" . -TEST_SUITES=(director director-xdp healthcheck redirect) +# The DPDK-based glb-director only builds on focal (DPDK 17 / KNI). +# On other distros, skip that suite; XDP is the supported forwarder. +if [[ "$DISTRO" == "focal" ]]; then + TEST_SUITES=(director director-xdp healthcheck redirect) +else + TEST_SUITES=(director-xdp healthcheck redirect) +fi for suite in "${TEST_SUITES[@]}"; do echo "" diff --git a/src/glb-director-xdp/bpf/Makefile b/src/glb-director-xdp/bpf/Makefile index fa114682..c0bc48db 100644 --- a/src/glb-director-xdp/bpf/Makefile +++ b/src/glb-director-xdp/bpf/Makefile @@ -1,14 +1,14 @@ all: glb_encap.o glb_encap_trace.o passer.o tailcall.o -CLANG=clang-10 -LLC=llc-10 +CLANG?=clang-10 +LLC?=llc-10 ifeq ($(KVER),) KVER=$(shell uname -r) endif %.o: %.c - $(CLANG) -c -O2 -emit-llvm -o - -D__KERNEL__ \ + $(CLANG) -c -O2 -emit-llvm -o - -D__KERNEL__ -g \ -Wall \ -Wno-gnu-variable-sized-type-not-at-end \ -Wno-address-of-packed-member \ @@ -23,6 +23,8 @@ endif -I /usr/src/linux-headers-$(KVER:-amd64=-common)/include/uapi \ -I /usr/src/linux-headers-$(KVER:-amd64=-common)/include \ -I /usr/src/linux-headers-$(KVER)/include \ + -I /usr/src/linux-headers-$(KVER)/arch/x86/include/generated \ + $(EXTRA_BPF_INCLUDES) \ -I include/ \ -I ../.. \ $< > .tmp.ll diff --git a/src/glb-director-xdp/bpf/glb_encap.c b/src/glb-director-xdp/bpf/glb_encap.c index 50bfc448..1badc98e 100644 --- a/src/glb-director-xdp/bpf/glb_encap.c +++ b/src/glb-director-xdp/bpf/glb_encap.c @@ -52,7 +52,12 @@ typedef struct { /* xdpcap integration */ #include "xdpcap_hook.h" -struct bpf_map_def SEC("maps") xdpcap_hook = XDPCAP_HOOK(); +struct { + __uint(type, BPF_MAP_TYPE_PROG_ARRAY); + __uint(key_size, sizeof(int)); + __uint(value_size, sizeof(int)); + __uint(max_entries, 5); +} xdpcap_hook SEC(".maps"); typedef struct glb_bind { uint32_t ipv4; @@ -61,11 +66,11 @@ typedef struct glb_bind { uint16_t port; } __attribute__((__packed__)) glb_bind_t; -struct bpf_map_def SEC("maps") config_bits = { - .type = BPF_MAP_TYPE_ARRAY, - .key_size = sizeof(uint32_t), - .value_size = 6, // maximum size stored - .max_entries = 5, +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(key_size, sizeof(uint32_t)); + __uint(value_size, 6); // maximum size stored + __uint(max_entries, 5); /* 0: 6 byes of gateway dst MAC @@ -74,36 +79,36 @@ struct bpf_map_def SEC("maps") config_bits = { 3: 4 bytes of glb_director_hash_fields 4: 4 bytes of glb_director_hash_fields (alt) */ -}; - -struct bpf_map_def SEC("maps") glb_binds = { - .type = BPF_MAP_TYPE_HASH, - .key_size = sizeof(struct glb_bind), - .value_size = sizeof(uint32_t), - .max_entries = BPF_MAX_BINDS, -}; - -struct bpf_map_def SEC("maps") glb_tables = { - .type = BPF_MAP_TYPE_ARRAY_OF_MAPS, - .key_size = sizeof(uint32_t), - .max_entries = 4096, -}; - -struct bpf_map_def SEC("maps") glb_table_secrets = { - .type = BPF_MAP_TYPE_ARRAY, - .key_size = sizeof(uint32_t), +} config_bits SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(key_size, sizeof(struct glb_bind)); + __uint(value_size, sizeof(uint32_t)); + __uint(max_entries, BPF_MAX_BINDS); +} glb_binds SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS); + __uint(key_size, sizeof(uint32_t)); + __uint(max_entries, 4096); +} glb_tables SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(key_size, sizeof(uint32_t)); #define GLB_FMT_SECURE_KEY_BYTES 16 - .value_size = GLB_FMT_SECURE_KEY_BYTES, - .max_entries = 4096, -}; - -struct bpf_map_def SEC("maps") glb_global_packet_counters = { - .type = BPF_MAP_TYPE_PERCPU_ARRAY, - .key_size = sizeof(uint32_t), - .value_size = sizeof(struct glb_global_stats), + __uint(value_size, GLB_FMT_SECURE_KEY_BYTES); + __uint(max_entries, 4096); +} glb_table_secrets SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); + __uint(key_size, sizeof(uint32_t)); + __uint(value_size, sizeof(struct glb_global_stats)); /* we don't actually need an array, but PERCPU_* only has multi-element types */ - .max_entries = 1, -}; + __uint(max_entries, 1); +} glb_global_packet_counters SEC(".maps"); static __always_inline uint16_t compute_ipv4_checksum(void *iph) { uint16_t *iph16 = (uint16_t *)iph; diff --git a/src/glb-director-xdp/bpf/tailcall.c b/src/glb-director-xdp/bpf/tailcall.c index 92b330da..839667f2 100644 --- a/src/glb-director-xdp/bpf/tailcall.c +++ b/src/glb-director-xdp/bpf/tailcall.c @@ -19,12 +19,12 @@ #define ROOT_ARRAY_SIZE 3 -struct bpf_map_def SEC("maps") root_array = { - .type = BPF_MAP_TYPE_PROG_ARRAY, - .key_size = sizeof(__u32), - .value_size = sizeof(__u32), - .max_entries = ROOT_ARRAY_SIZE, -}; +struct { + __uint(type, BPF_MAP_TYPE_PROG_ARRAY); + __uint(key_size, sizeof(__u32)); + __uint(value_size, sizeof(__u32)); + __uint(max_entries, ROOT_ARRAY_SIZE); +} root_array SEC(".maps"); SEC("xdp-root") int xdp_root(struct xdp_md *ctx) { diff --git a/src/glb-director-xdp/bpf/xdpcap_hook.h b/src/glb-director-xdp/bpf/xdpcap_hook.h index c190161d..3cd72ac2 100644 --- a/src/glb-director-xdp/bpf/xdpcap_hook.h +++ b/src/glb-director-xdp/bpf/xdpcap_hook.h @@ -38,7 +38,16 @@ * Create a bpf map suitable for use as an xdpcap hook point. * * For example: - * struct bpf_map_def xdpcap_hook = XDPCAP_HOOK(); + * struct { + * __uint(type, BPF_MAP_TYPE_PROG_ARRAY); + * __uint(key_size, sizeof(int)); + * __uint(value_size, sizeof(int)); + * __uint(max_entries, 5); + * } xdpcap_hook SEC(".maps"); + * + * The legacy XDPCAP_HOOK() initializer macro is kept for source compat with + * older callers but new code should declare the map directly using the BTF + * style above (libbpf 1.0+ rejects the legacy "maps" section). */ #define XDPCAP_HOOK() { \ .type = BPF_MAP_TYPE_PROG_ARRAY, \ diff --git a/src/glb-director-xdp/main.go b/src/glb-director-xdp/main.go index 07e3d602..3afca1cb 100644 --- a/src/glb-director-xdp/main.go +++ b/src/glb-director-xdp/main.go @@ -97,6 +97,11 @@ typedef struct { #include "../glb-director/glb_fwd_config.c" +// Single definition of the global debug flag declared (extern) in log.h. +// glb_fwd_config.c -> log.h is the only translation unit in this xdp build +// that references it, so define it once here. +bool debug = false; + // cgo borked zero-size trailing arrays, so we return the pointer instead. struct glb_fwd_config_content_table *_get_tables(struct glb_fwd_config_content *content) { return content->tables; diff --git a/src/glb-director-xdp/script/create-packages b/src/glb-director-xdp/script/create-packages index 8288edea..b7e5d461 100755 --- a/src/glb-director-xdp/script/create-packages +++ b/src/glb-director-xdp/script/create-packages @@ -36,7 +36,10 @@ cd $ROOTDIR . packaging/version.sh -make -C ../glb-director/cli +# Only the cli tool is needed to build forwarding tables; avoid building the +# rest of the cli/ targets (glb-config-check, glb-director-pcap, ...) since +# they link DPDK and won't compile on distros without DPDK 17 (e.g. noble). +make -C ../glb-director/cli glb-director-cli make ../glb-director/cli/glb-director-cli build-config ../glb-director/packaging/forwarding_table.json ../glb-director/packaging/forwarding_table.bin @@ -45,7 +48,7 @@ fpm -f -s dir -t deb \ -n glb-director-xdp \ -v ${GLB_DIRECTOR_XDP_VERSION} \ -d "xdp-root-shim" \ - -d "libbpf0" \ + -d "libbpf1 | libbpf0" \ -d "glb-director-cli >= ${GLB_DIRECTOR_VERSION}" \ --conflicts 'glb-director' \ --license 'BSD 3-Clause' \ @@ -64,7 +67,7 @@ fpm -f -s dir -t deb \ fpm -f -s dir -t deb \ -n xdp-root-shim \ -v ${XDP_ROOT_SHIM_VERSION} \ - -d "libbpf0" \ + -d "libbpf1 | libbpf0" \ --license 'BSD 3-Clause' \ --maintainer 'GitHub ' \ --deb-systemd packaging/xdp-root-shim\@.service \ diff --git a/src/glb-director-xdp/script/test b/src/glb-director-xdp/script/test index 9ad0844a..ea51ad17 100755 --- a/src/glb-director-xdp/script/test +++ b/src/glb-director-xdp/script/test @@ -42,7 +42,7 @@ export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin begin_fold "Building glb-director-xdp for testing" ( - make -j4 -C ../glb-director/cli + make -j4 -C ../glb-director/cli glb-director-cli make # scan-build bricks go ) end_fold diff --git a/src/glb-director-xdp/xdp-root-shim/xdp-root-shim.c b/src/glb-director-xdp/xdp-root-shim/xdp-root-shim.c index ec66f072..daae90d3 100644 --- a/src/glb-director-xdp/xdp-root-shim/xdp-root-shim.c +++ b/src/glb-director-xdp/xdp-root-shim/xdp-root-shim.c @@ -38,6 +38,18 @@ #include #include +/* libbpf 0.6 introduced bpf/libbpf_version.h with LIBBPF_MAJOR_VERSION. + * Older releases (e.g. libbpf 0.0.6 shipped on Ubuntu focal) don't have it. */ +#if __has_include() +#include +#endif + +#if defined(LIBBPF_MAJOR_VERSION) && LIBBPF_MAJOR_VERSION >= 1 +#define GLB_LIBBPF_MODERN 1 +#else +#define GLB_LIBBPF_MODERN 0 +#endif + int main(int argc, char **argv) { if (argc != 4) { fprintf(stderr, "Usage: %s \n", argv[0]); @@ -70,7 +82,38 @@ int main(int argc, char **argv) { return 1; } - /* load the tailcall bpf */ + /* load the tailcall bpf + * + * libbpf 1.0+ (shipped on ubuntu noble) removed bpf_prog_load_xattr() and + * bpf_set_link_xdp_fd(). Use the modern open-file / load / attach API on + * noble, and fall back to the legacy API on focal (libbpf 0.0.x). + */ +#if GLB_LIBBPF_MODERN + struct bpf_object *shim_obj = bpf_object__open_file(tailcall_elf_path, NULL); + if (!shim_obj || libbpf_get_error(shim_obj)) { + fprintf(stderr, "Could not open '%s'\n", tailcall_elf_path); + return 1; + } + + /* force every program in the object to load as XDP */ + struct bpf_program *prog; + bpf_object__for_each_program(prog, shim_obj) { + bpf_program__set_type(prog, BPF_PROG_TYPE_XDP); + } + + if (bpf_object__load(shim_obj) != 0) { + fprintf(stderr, "Could not load '%s'\n", tailcall_elf_path); + return 1; + } + + /* find the first XDP program in the object to attach to the iface */ + prog = bpf_object__next_program(shim_obj, NULL); + if (!prog) { + fprintf(stderr, "No BPF programs found in '%s'\n", tailcall_elf_path); + return 1; + } + int prog_fd = bpf_program__fd(prog); +#else struct bpf_prog_load_attr prog_load_attr = { .prog_type = BPF_PROG_TYPE_XDP, .file = tailcall_elf_path, @@ -82,18 +125,27 @@ int main(int argc, char **argv) { fprintf(stderr, "Could not load '%s'\n", prog_load_attr.file); return 1; } +#endif - /* pin the map to the */ + /* pin the map to the bpffs */ struct bpf_map *root_array = bpf_object__find_map_by_name(shim_obj, "root_array"); + if (!root_array) { + fprintf(stderr, "Could not find map 'root_array' in '%s'\n", tailcall_elf_path); + return 1; + } unlink(bpffs_path); if (bpf_map__pin(root_array, bpffs_path) != 0) { fprintf(stderr, "Could not pin root array map to '%s'\n", bpffs_path); return 1; } - + /* bind it to the interface with XDP */ +#if GLB_LIBBPF_MODERN + if (bpf_xdp_attach(iface_index, prog_fd, 0, NULL) < 0) { +#else if (bpf_set_link_xdp_fd(iface_index, prog_fd, 0) < 0) { +#endif fprintf(stderr, "Could not attach XDP program to interface '%s'\n", iface_name); return 1; } diff --git a/src/glb-director/cli/main.c b/src/glb-director/cli/main.c index b6d539e4..0302ab38 100644 --- a/src/glb-director/cli/main.c +++ b/src/glb-director/cli/main.c @@ -43,6 +43,12 @@ #include "log.h" +/* Standalone definition of the global debug flag declared in log.h. + * The cli/glb-director-cli target compiles only main.c + siphash24.c, so it + * needs to provide its own definition (other targets get it from shared_opt.c + * or, for test-check-config, from tests/test_check_config.c). */ +bool debug = false; + #define GLB_BACKEND_HEALTH_DOWN 0 #define GLB_BACKEND_HEALTH_UP 1 diff --git a/src/glb-director/log.h b/src/glb-director/log.h index 58c4da2c..cd8e8cde 100644 --- a/src/glb-director/log.h +++ b/src/glb-director/log.h @@ -36,7 +36,7 @@ #include #define MAX_MESSAGE_SZ 1024 -bool debug; +extern bool debug; // outputs formatted logs to stdout or stderr diff --git a/src/glb-director/script/create-packages b/src/glb-director/script/create-packages index b3811ef3..dbccb26c 100755 --- a/src/glb-director/script/create-packages +++ b/src/glb-director/script/create-packages @@ -36,6 +36,29 @@ cd $ROOTDIR . packaging/version.sh +# GLB_CLI_ONLY=1 builds and packages only glb-director-cli (no DPDK). +# Used on distros where the DPDK director is not built (e.g. noble), but where +# glb-director-cli is still required as a runtime dep of glb-director-xdp. +if [ "${GLB_CLI_ONLY:-0}" = "1" ]; then + make -C cli clean + make -C cli glb-director-cli + + fpm -f -s dir -t deb \ + -n glb-director-cli \ + -v ${GLB_DIRECTOR_VERSION} \ + -d 'libjansson4' \ + --license 'BSD 3-Clause' \ + --maintainer 'GitHub ' \ + cli/glb-director-cli=/usr/sbin/ + + if [ -d "$BUILDDIR" ]; then + cp glb-director-cli_${GLB_DIRECTOR_VERSION}_amd64.deb $BUILDDIR/ + fi + + make -C cli clean + exit 0 +fi + make clean make -C cli clean diff --git a/src/glb-director/shared_opt.c b/src/glb-director/shared_opt.c index 5070a65b..7bbaaa57 100644 --- a/src/glb-director/shared_opt.c +++ b/src/glb-director/shared_opt.c @@ -33,6 +33,12 @@ #include "shared_opt.h" #include +/* Single definition of the global debug flag declared in log.h / shared_opt.h. + * Newer GCC defaults to -fno-common, so a tentative definition in the header + * (the original `bool debug;` in log.h) is rejected as a duplicate symbol when + * multiple translation units include it. */ +bool debug = false; + /* parses --config-file, --forwarding-table, and --debug cli options */ void get_options(char *config_file, char *forwarding_table, int argc,