Skip to content

Comments

[calico-node] Enable CGO builds for ppc64le#11707

Open
kishen-v wants to merge 2 commits intoprojectcalico:masterfrom
kishen-v:cgo-ppc64le
Open

[calico-node] Enable CGO builds for ppc64le#11707
kishen-v wants to merge 2 commits intoprojectcalico:masterfrom
kishen-v:cgo-ppc64le

Conversation

@kishen-v
Copy link
Contributor

@kishen-v kishen-v commented Jan 22, 2026

Description

This PR aims at enabling CGO builds for the ppc64le architecture. Post merge, it would remediate the issue tied to the "BPF syscall stub" panic observed on PowerPC nodes during startup. The changes are based on arm64 related CGO enablement.

Previously, ppc64le builds relied on CGO_ENABLED=0, which forced the usage of unimplemented BPF stubs. This had caused panics when the startup logic unconditionally invoked these BPF functions.

This PR contains the following changes:

  • Enabling CGO for ppc64le to link against the actual libbpf implementation.
  • Adding the missing LDFLAGS under felix/bpf/libbpf/libbpf.go
  • Fixing a C type alignment (__u64 vs ulonglong) that prevented compilation on PowerPC.

Please let me know if any supporting changes are needed in this PR. Thanks!

With the changes: 

[root@p10-image-builder node]# kubectl exec -it calico-node-v5stw -n kube-system -- calico-node -v
Defaulted container "calico-node" out of: calico-node, upgrade-ipam (init), install-cni (init), ebpf-bootstrap (init)
Version:      9a6566b741c7
Build date:   2026-01-22T17:13:55+0000
Git commit:   9a6566b741c77aed930383f633f98e7b5d35886b

[root@p10-image-builder node]# kubectl get pods -A
NAMESPACE     NAME                                      READY   STATUS    RESTARTS       AGE
default       nginx                                     1/1     Running   0              7h46m
kube-system   calico-kube-controllers-9b54b4c6c-lbl54   1/1     Running   0              27h
kube-system   calico-node-czx2s                         1/1     Running   0              74s
kube-system   calico-node-v5stw                         1/1     Running   0              52s
kube-system   coredns-674b8bbfcf-8gmsb                  1/1     Running   0              5h55m
kube-system   coredns-674b8bbfcf-9dqcd                  1/1     Running   0              5h55m
kube-system   etcd-kish-k8s-1                           1/1     Running   1 (141d ago)   197d
kube-system   kube-apiserver-kish-k8s-1                 1/1     Running   4 (106d ago)   197d
kube-system   kube-controller-manager-kish-k8s-1        1/1     Running   4 (106d ago)   197d
kube-system   kube-proxy-7rj4z                          1/1     Running   1 (141d ago)   197d
kube-system   kube-proxy-dc4rn                          1/1     Running   1 (141d ago)   197d
kube-system   kube-scheduler-kish-k8s-1                 1/1     Running   4 (106d ago)   197d

Related issues/PRs: #11703

Todos

  • Tests
  • Documentation
  • Release note

Release Note

Support CGO Enabled builds for ppc64le

Reminder for the reviewer

Make sure that this PR has the correct labels and milestone set.

Every PR needs one docs-* label.

  • docs-pr-required: This change requires a change to the documentation that has not been completed yet.
  • docs-completed: This change has all necessary documentation completed.
  • docs-not-required: This change has no user-facing impact and requires no docs.

Every PR needs one release-note-* label.

  • release-note-required: This PR has user-facing changes. Most PRs should have this label.
  • release-note-not-required: This PR has no user-facing changes.

Other optional labels:

  • cherry-pick-candidate: This PR should be cherry-picked to an earlier release. For bug fixes only.
  • needs-operator-pr: This PR is related to install and requires a corresponding change to the operator.

@kishen-v kishen-v requested a review from a team as a code owner January 22, 2026 17:18
@marvin-tigera marvin-tigera added this to the Calico v3.32.0 milestone Jan 22, 2026
@marvin-tigera marvin-tigera added release-note-required Change has user-facing impact (no matter how small) docs-pr-required Change is not yet documented labels Jan 22, 2026
defer C.free(cV)

C.bpf_maps_attr_setup_map_elem(bpfAttr, C.uint(mapFD), cK, cV, C.ulonglong(flags))
C.bpf_maps_attr_setup_map_elem(bpfAttr, C.uint(mapFD), cK, cV, C.__u64(flags))
Copy link
Contributor Author

@kishen-v kishen-v Jan 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On ppc64le , __u64 is defined as unsigned long, whereas on amd64 it is unsigned long long. Casting to C.ulonglong causes a CGO type mismatch on ppc64le. Since the function signature already expects __u64, the value is kept as-is from the definition.

Reference:
void bpf_maps_attr_setup_map_elem(union bpf_attr *attr, __u32 map_fd, void *pointer_to_key, void *pointer_to_value, __u64 flags

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously, I used -D__SANE_USERSPACE_TYPES__ to get int-ll64.h included for ppc64le builds. I’m not sure whether this is preferable to using __u64, or if it’s the right way to work around the build issue. Just sharing for contexts.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @hjiawei, I've adopted the usage of -D__SANE_USERSPACE_TYPES__ in Makefiles, wherever necessary to have a minimal diff in *.go files.
Thanks!

@hjiawei
Copy link
Contributor

hjiawei commented Jan 23, 2026

Do we need the ppc64le CFLAGS definitions in felix/bpf-gpl/Makefile?

ifeq ($(findstring x86_64,$(TRIPLET)),x86_64)
CFLAGS += -D__TARGET_ARCH_x86 -D__x86_64__
else ifeq ($(findstring aarch64,$(TRIPLET)),aarch64)
CFLAGS += -D__TARGET_ARCH_arm64
endif

--- a/felix/bpf-gpl/Makefile
+++ b/felix/bpf-gpl/Makefile
@@ -51,6 +51,8 @@ ifeq ($(findstring x86_64,$(TRIPLET)),x86_64)
        CFLAGS += -D__TARGET_ARCH_x86 -D__x86_64__
 else ifeq ($(findstring aarch64,$(TRIPLET)),aarch64)
        CFLAGS += -D__TARGET_ARCH_arm64
+else ifeq ($(findstring ppc64le,$(TRIPLET)),ppc64le)
+       CFLAGS += -D__TARGET_ARCH_powerpc -D__SANE_USERSPACE_TYPES__
 endif
 CC := clang
 LD := llc

@kishen-v kishen-v changed the title [calico-node] Enable CGO builds for ppc64le [WIP][calico-node] Enable CGO builds for ppc64le Jan 27, 2026
@hjiawei hjiawei requested a review from Copilot January 28, 2026 00:09
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Enable CGO builds for the ppc64le architecture so Calico can link against real libbpf (avoiding the BPF syscall stub panic on PowerPC nodes).

Changes:

  • Enable CGO for ppc64le in node and felix build Makefiles (including adding __SANE_USERSPACE_TYPES__ for PowerPC).
  • Add missing ppc64le CGO LDFLAGS for libbpf linkage in Felix.
  • Update the ppc64le node image Dockerfile to a glibc/UBI-based build flow consistent with other arches.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
node/Makefile Enables CGO for ppc64le and sets PowerPC-specific CGO CFLAGS to support real libbpf usage.
node/Dockerfile.ppc64le Moves ppc64le node image to the UBI/AlmaLinux-based build pattern needed for CGO-linked binaries.
felix/bpf/libbpf/libbpf.go Adds ppc64le-specific CGO LDFLAGS to link against the ppc64le libbpf build output.
felix/bpf-gpl/Makefile Adds PowerPC target defines for BPF program compilation on ppc64le.
felix/Makefile Enables CGO for ppc64le and adds PowerPC-specific CGO CFLAGS consistent with the node build.

Comment on lines 15 to +22
ARG BIRD_IMAGE=calico/bird:latest

FROM ${BIRD_IMAGE} AS bird

FROM calico/bpftool:v7.4.0 AS bpftool
FROM ${BIRD_IMAGE} AS bird
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Dockerfile hard-codes the bpftool image (calico/bpftool:v7.4.0) instead of using the repo-wide pinned BPFTOOL_IMAGE value (see metadata.mk and how node/Dockerfile.amd64 uses ARG BPFTOOL_IMAGE + FROM ${BPFTOOL_IMAGE}). This can cause version skew between architectures and makes it harder to bump bpftool consistently. Consider switching this file to the same BPFTOOL_IMAGE build-arg pattern (or at least updating the hard-coded tag to match the current pin).

Copilot uses AI. Check for mistakes.
Comment on lines +93 to +95
# Update base packages to pick up security updates. Must do this before adding the AlmaLinux repo.
RUN microdnf upgrade -y

Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RUN microdnf upgrade -y is inconsistent with the other node Dockerfiles (e.g. node/Dockerfile.arm64 / node/Dockerfile.amd64 use RUN microdnf upgrade without -y). It’d be better to align this for consistency unless -y is required for ppc64le specifically.

Copilot uses AI. Check for mistakes.
Comment on lines +81 to +84
RUN curl -sfL https://ftp.debian.org/debian/pool/main/r/runit/runit_${RUNIT_VER}.orig.tar.gz | tar xz -C /root && \
cd /root/admin/runit-${RUNIT_VER} && \
patch -p1 < /svlogd_use_0644_permission_instead_of_0744.patch && \
package/compile
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The almalinux build stage downloads and executes runit source via curl from https://ftp.debian.org/.../runit_${RUNIT_VER}.orig.tar.gz without any integrity verification. If an attacker can tamper with that distribution path (e.g., compromise the mirror/DNS/TLS), they could inject malicious code into the built image that then runs with root privileges at runtime. To reduce this supply-chain risk, ensure the downloaded archive is verified using a pinned checksum or GPG signature, or obtain it via a package manager that performs signature verification.

Copilot uses AI. Check for mistakes.
@coutinhop
Copy link
Member

/sem-approve

@kishen-v
Copy link
Contributor Author

Re-tested with the latest changes, the cross-built image works as intended:

[root@image-builder ~]# kubectl exec -it calico-node-f5wds -n kube-system -- /bin/calico-node -v
Defaulted container "calico-node" out of: calico-node, upgrade-ipam (init), install-cni (init), ebpf-bootstrap (init)
Version:      507a57704414
Build date:   2026-01-28T06:21:36+0000
Git commit:   507a57704414c713dbe23de1ecd91da0428724dc

build: fix cross-compilation for felix on ppc64le.

Co-authored-by: Pedro Coutinho <coutinhop@users.noreply.github.com>
@kishen-v kishen-v changed the title [WIP][calico-node] Enable CGO builds for ppc64le [calico-node] Enable CGO builds for ppc64le Jan 29, 2026
@kishen-v
Copy link
Contributor Author

kishen-v commented Feb 3, 2026

Hey @coutinhop and @hjiawei,
Thanks for taking a look at the PR! Please let me know if any further changes are needed.

@hjiawei
Copy link
Contributor

hjiawei commented Feb 3, 2026

/sem-approve

@hjiawei hjiawei mentioned this pull request Feb 3, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs-pr-required Change is not yet documented release-note-required Change has user-facing impact (no matter how small)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants